@salesforce/plugin-devops-center 1.3.0 → 1.4.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 (185) hide show
  1. package/README.md +649 -102
  2. package/lib/commands/devops/pipeline/create.d.ts +2 -1
  3. package/lib/commands/devops/pipeline/create.js +37 -7
  4. package/lib/commands/devops/pipeline/create.js.map +1 -1
  5. package/lib/commands/devops/pipeline/{activate.d.ts → get.d.ts} +3 -3
  6. package/lib/commands/devops/pipeline/get.js +81 -0
  7. package/lib/commands/devops/pipeline/get.js.map +1 -0
  8. package/lib/commands/devops/pipeline/list.d.ts +13 -0
  9. package/lib/commands/devops/pipeline/list.js +58 -0
  10. package/lib/commands/devops/pipeline/list.js.map +1 -0
  11. package/lib/commands/devops/pipeline/{attach-project.d.ts → project/add.d.ts} +2 -2
  12. package/lib/commands/devops/pipeline/{attach-project.js → project/add.js} +5 -5
  13. package/lib/commands/devops/pipeline/project/add.js.map +1 -0
  14. package/lib/commands/devops/pipeline/project/delete.d.ts +15 -0
  15. package/lib/commands/devops/pipeline/{activate.js → project/delete.js} +17 -28
  16. package/lib/commands/devops/pipeline/project/delete.js.map +1 -0
  17. package/lib/commands/devops/pipeline/stage/delete.d.ts +15 -0
  18. package/lib/commands/devops/pipeline/stage/delete.js +69 -0
  19. package/lib/commands/devops/pipeline/stage/delete.js.map +1 -0
  20. package/lib/commands/devops/pipeline/update.d.ts +18 -0
  21. package/lib/commands/devops/pipeline/update.js +126 -0
  22. package/lib/commands/devops/pipeline/update.js.map +1 -0
  23. package/lib/commands/devops/project/update.d.ts +17 -0
  24. package/lib/commands/devops/project/update.js +86 -0
  25. package/lib/commands/devops/project/update.js.map +1 -0
  26. package/lib/commands/devops/promote.d.ts +24 -0
  27. package/lib/commands/devops/promote.js +148 -0
  28. package/lib/commands/devops/promote.js.map +1 -0
  29. package/lib/commands/devops/promotion/complete.d.ts +20 -0
  30. package/lib/commands/devops/promotion/complete.js +112 -0
  31. package/lib/commands/devops/promotion/complete.js.map +1 -0
  32. package/lib/commands/devops/request/status.d.ts +14 -0
  33. package/lib/commands/devops/request/status.js +71 -0
  34. package/lib/commands/devops/request/status.js.map +1 -0
  35. package/lib/commands/devops/{pull-request → review}/create.d.ts +1 -3
  36. package/lib/commands/devops/{pull-request → review}/create.js +11 -43
  37. package/lib/commands/devops/review/create.js.map +1 -0
  38. package/lib/commands/devops/stage/{add-branch.d.ts → branch/add.d.ts} +2 -2
  39. package/lib/commands/devops/stage/{add-branch.js → branch/add.js} +6 -6
  40. package/lib/commands/devops/stage/branch/add.js.map +1 -0
  41. package/lib/commands/devops/stage/{add-environment.d.ts → environment/add.d.ts} +2 -2
  42. package/lib/commands/devops/stage/{add-environment.js → environment/add.js} +13 -6
  43. package/lib/commands/devops/stage/environment/add.js.map +1 -0
  44. package/lib/commands/devops/stage/environment/delete.d.ts +15 -0
  45. package/lib/commands/devops/stage/environment/delete.js +75 -0
  46. package/lib/commands/devops/stage/environment/delete.js.map +1 -0
  47. package/lib/commands/devops/work-item/combine.d.ts +15 -0
  48. package/lib/commands/devops/work-item/combine.js +109 -0
  49. package/lib/commands/devops/work-item/combine.js.map +1 -0
  50. package/lib/commands/devops/work-item/prepare.d.ts +14 -0
  51. package/lib/commands/devops/work-item/prepare.js +98 -0
  52. package/lib/commands/devops/work-item/prepare.js.map +1 -0
  53. package/lib/commands/devops/work-item/{status/update.d.ts → update.d.ts} +6 -4
  54. package/lib/commands/devops/work-item/{status/update.js → update.js} +30 -9
  55. package/lib/commands/devops/work-item/update.js.map +1 -0
  56. package/lib/common/flags/promote/promoteFlags.d.ts +1 -0
  57. package/lib/common/flags/promote/promoteFlags.js +5 -0
  58. package/lib/common/flags/promote/promoteFlags.js.map +1 -1
  59. package/lib/common/outputService/aorOutputService.js +4 -4
  60. package/lib/common/outputService/aorOutputService.js.map +1 -1
  61. package/lib/common/outputService/outputUtils.js +1 -2
  62. package/lib/common/outputService/outputUtils.js.map +1 -1
  63. package/lib/common/selectors/asyncOperationResultsSelector.js +3 -1
  64. package/lib/common/selectors/asyncOperationResultsSelector.js.map +1 -1
  65. package/lib/common/selectors/deployComponentsSelector.js +5 -6
  66. package/lib/common/selectors/deployComponentsSelector.js.map +1 -1
  67. package/lib/common/selectors/deployProgressSummarySelector.js +3 -1
  68. package/lib/common/selectors/deployProgressSummarySelector.js.map +1 -1
  69. package/lib/common/selectors/deploymentResultsSelector.js +10 -6
  70. package/lib/common/selectors/deploymentResultsSelector.js.map +1 -1
  71. package/lib/common/selectors/environmentSelector.js +4 -2
  72. package/lib/common/selectors/environmentSelector.js.map +1 -1
  73. package/lib/common/selectors/namedCredentialSelector.js +2 -1
  74. package/lib/common/selectors/namedCredentialSelector.js.map +1 -1
  75. package/lib/common/selectors/pipelineStageSelector.js +5 -3
  76. package/lib/common/selectors/pipelineStageSelector.js.map +1 -1
  77. package/lib/common/selectors/validateDeploySelector.js +3 -1
  78. package/lib/common/selectors/validateDeploySelector.js.map +1 -1
  79. package/lib/common/selectors/workItemSelector.js +4 -1
  80. package/lib/common/selectors/workItemSelector.js.map +1 -1
  81. package/lib/utils/activatePipeline.d.ts +13 -4
  82. package/lib/utils/activatePipeline.js +7 -6
  83. package/lib/utils/activatePipeline.js.map +1 -1
  84. package/lib/utils/attachProject.js +2 -0
  85. package/lib/utils/attachProject.js.map +1 -1
  86. package/lib/utils/combineWorkItems.d.ts +20 -0
  87. package/lib/utils/combineWorkItems.js +42 -0
  88. package/lib/utils/combineWorkItems.js.map +1 -0
  89. package/lib/utils/createPipeline.d.ts +14 -1
  90. package/lib/utils/createPipeline.js +52 -6
  91. package/lib/utils/createPipeline.js.map +1 -1
  92. package/lib/utils/createProject.js +1 -0
  93. package/lib/utils/createProject.js.map +1 -1
  94. package/lib/utils/createPullRequest.d.ts +7 -19
  95. package/lib/utils/createPullRequest.js +51 -122
  96. package/lib/utils/createPullRequest.js.map +1 -1
  97. package/lib/utils/deletePipelineStage.d.ts +12 -0
  98. package/lib/utils/deletePipelineStage.js +41 -0
  99. package/lib/utils/deletePipelineStage.js.map +1 -0
  100. package/lib/utils/deleteStageEnvironment.d.ts +8 -0
  101. package/lib/utils/deleteStageEnvironment.js +33 -0
  102. package/lib/utils/deleteStageEnvironment.js.map +1 -0
  103. package/lib/utils/deployStage.d.ts +29 -0
  104. package/lib/utils/deployStage.js +68 -0
  105. package/lib/utils/deployStage.js.map +1 -0
  106. package/lib/utils/detachProject.d.ts +8 -0
  107. package/lib/utils/detachProject.js +37 -0
  108. package/lib/utils/detachProject.js.map +1 -0
  109. package/lib/utils/getPipeline.d.ts +27 -0
  110. package/lib/utils/getPipeline.js +66 -0
  111. package/lib/utils/getPipeline.js.map +1 -0
  112. package/lib/utils/getRequestStatus.d.ts +10 -0
  113. package/lib/utils/getRequestStatus.js +32 -0
  114. package/lib/utils/getRequestStatus.js.map +1 -0
  115. package/lib/utils/listPipelines.d.ts +11 -0
  116. package/lib/utils/listPipelines.js +20 -0
  117. package/lib/utils/listPipelines.js.map +1 -0
  118. package/lib/utils/pipelineUtils.js +3 -0
  119. package/lib/utils/pipelineUtils.js.map +1 -1
  120. package/lib/utils/prepareWorkItem.d.ts +25 -0
  121. package/lib/utils/prepareWorkItem.js +55 -0
  122. package/lib/utils/prepareWorkItem.js.map +1 -0
  123. package/lib/utils/promoteStage.d.ts +21 -0
  124. package/lib/utils/promoteStage.js +46 -0
  125. package/lib/utils/promoteStage.js.map +1 -0
  126. package/lib/utils/soqlUtils.d.ts +23 -0
  127. package/lib/utils/soqlUtils.js +63 -0
  128. package/lib/utils/soqlUtils.js.map +1 -0
  129. package/lib/utils/updateProject.d.ts +17 -0
  130. package/lib/utils/updateProject.js +41 -0
  131. package/lib/utils/updateProject.js.map +1 -0
  132. package/lib/utils/{updateWorkItemStatus.d.ts → updateWorkItem.d.ts} +12 -14
  133. package/lib/utils/{updateWorkItemStatus.js → updateWorkItem.js} +31 -27
  134. package/lib/utils/updateWorkItem.js.map +1 -0
  135. package/lib/utils/workItems.js +2 -0
  136. package/lib/utils/workItems.js.map +1 -1
  137. package/messages/devops.pipeline.create.md +26 -6
  138. package/messages/devops.pipeline.get.md +17 -0
  139. package/messages/devops.pipeline.list.md +13 -0
  140. package/messages/devops.pipeline.project.delete.md +25 -0
  141. package/messages/devops.pipeline.stage.delete.md +25 -0
  142. package/messages/devops.pipeline.update.md +47 -0
  143. package/messages/devops.project.update.md +45 -0
  144. package/messages/devops.promote.md +61 -0
  145. package/messages/devops.promotion.complete.md +47 -0
  146. package/messages/devops.request.status.md +21 -0
  147. package/messages/devops.review.create.md +33 -0
  148. package/messages/{devops.stage.add-environment.md → devops.stage.environment.add.md} +4 -0
  149. package/messages/devops.stage.environment.delete.md +29 -0
  150. package/messages/devops.work-item.combine.md +39 -0
  151. package/messages/devops.work-item.prepare.md +27 -0
  152. package/messages/devops.work-item.update.md +45 -0
  153. package/npm-shrinkwrap.json +37 -174
  154. package/oclif.lock +1 -1
  155. package/oclif.manifest.json +1167 -223
  156. package/package.json +20 -8
  157. package/schemas/devops-pipeline-get.json +98 -0
  158. package/schemas/devops-pipeline-list.json +38 -0
  159. package/schemas/devops-pipeline-project-delete.json +25 -0
  160. package/schemas/devops-pipeline-stage-delete.json +25 -0
  161. package/schemas/{devops-pipeline-activate.json → devops-pipeline-update.json} +5 -2
  162. package/schemas/devops-project-update.json +31 -0
  163. package/schemas/devops-promote.json +28 -0
  164. package/schemas/devops-promotion-complete.json +34 -0
  165. package/schemas/devops-request-status.json +31 -0
  166. package/schemas/{devops-pull__request-create.json → devops-review-create.json} +0 -3
  167. package/schemas/devops-stage-environment-delete.json +25 -0
  168. package/schemas/devops-work__item-combine.json +25 -0
  169. package/schemas/devops-work__item-prepare.json +25 -0
  170. package/schemas/{devops-work__item-status-update.json → devops-work__item-update.json} +8 -2
  171. package/lib/commands/devops/pipeline/activate.js.map +0 -1
  172. package/lib/commands/devops/pipeline/attach-project.js.map +0 -1
  173. package/lib/commands/devops/pull-request/create.js.map +0 -1
  174. package/lib/commands/devops/stage/add-branch.js.map +0 -1
  175. package/lib/commands/devops/stage/add-environment.js.map +0 -1
  176. package/lib/commands/devops/work-item/status/update.js.map +0 -1
  177. package/lib/utils/updateWorkItemStatus.js.map +0 -1
  178. package/messages/devops.pipeline.activate.md +0 -29
  179. package/messages/devops.pull-request.create.md +0 -57
  180. package/messages/devops.work-item.status.update.md +0 -29
  181. /package/messages/{devops.pipeline.attach-project.md → devops.pipeline.project.add.md} +0 -0
  182. /package/messages/{devops.stage.add-branch.md → devops.stage.branch.add.md} +0 -0
  183. /package/schemas/{devops-pipeline-attach__project.json → devops-pipeline-project-add.json} +0 -0
  184. /package/schemas/{devops-stage-add__branch.json → devops-stage-branch-add.json} +0 -0
  185. /package/schemas/{devops-stage-add__environment.json → devops-stage-environment-add.json} +0 -0
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { fetchPipelineStages } from './pipelineUtils.js';
17
+ /**
18
+ * Deletes a pipeline stage and re-links any predecessor stage so the chain stays intact.
19
+ * If stage B sits between A→B→C, deleting B updates A's NextStageId to C before the delete.
20
+ */
21
+ export async function deletePipelineStage(connection, pipelineId, stageId) {
22
+ const stages = await fetchPipelineStages(connection, pipelineId);
23
+ const target = stages.find((s) => s.Id === stageId);
24
+ if (!target) {
25
+ throw new Error(`Stage not found: ${stageId}`);
26
+ }
27
+ const predecessor = stages.find((s) => s.NextStageId === stageId);
28
+ if (predecessor) {
29
+ await connection
30
+ .sobject('DevopsPipelineStage')
31
+ .update({ Id: predecessor.Id, NextStageId: target.NextStageId ?? null });
32
+ }
33
+ const result = await connection.sobject('DevopsPipelineStage').delete(stageId);
34
+ const deleteResult = result;
35
+ if (!deleteResult.success) {
36
+ const errorMsg = deleteResult.errors?.map((e) => e.message).join('; ') ?? 'Unknown error';
37
+ return { success: false, error: errorMsg };
38
+ }
39
+ return { success: true, stageId, pipelineId };
40
+ }
41
+ //# sourceMappingURL=deletePipelineStage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deletePipelineStage.js","sourceRoot":"","sources":["../../src/utils/deletePipelineStage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AASzD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,UAAsB,EACtB,UAAkB,EAClB,OAAe;IAEf,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACjE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,OAAO,CAAC,CAAC;IAClE,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,UAAU;aACb,OAAO,CAAC,qBAAqB,CAAC;aAC9B,MAAM,CAAC,EAAE,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,IAAI,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/E,MAAM,YAAY,GAAG,MAA8E,CAAC;IAEpG,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;QAC1F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;AAChD,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Connection } from '@salesforce/core';
2
+ export type DeleteStageEnvironmentResult = {
3
+ success: boolean;
4
+ environmentId?: string;
5
+ stageId?: string;
6
+ error?: string;
7
+ };
8
+ export declare function deleteStageEnvironment(connection: Connection, environmentId: string): Promise<DeleteStageEnvironmentResult>;
@@ -0,0 +1,33 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { validateSalesforceId } from './soqlUtils.js';
17
+ export async function deleteStageEnvironment(connection, environmentId) {
18
+ validateSalesforceId(environmentId, 'environment');
19
+ const stageResult = await connection.query(`SELECT Id FROM DevopsPipelineStage WHERE DevOpsEnvironmentId = '${environmentId}'`);
20
+ const referencingStages = stageResult.records ?? [];
21
+ if (referencingStages.length > 0) {
22
+ const updates = referencingStages.map((s) => ({ Id: s.Id, DevOpsEnvironmentId: null }));
23
+ await connection.sobject('DevopsPipelineStage').update(updates);
24
+ }
25
+ const result = await connection.sobject('DevopsEnvironment').delete(environmentId);
26
+ const deleteResult = result;
27
+ if (!deleteResult.success) {
28
+ const errorMsg = deleteResult.errors?.map((e) => e.message).join('; ') ?? 'Unknown error';
29
+ return { success: false, error: errorMsg };
30
+ }
31
+ return { success: true, environmentId };
32
+ }
33
+ //# sourceMappingURL=deleteStageEnvironment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deleteStageEnvironment.js","sourceRoot":"","sources":["../../src/utils/deleteStageEnvironment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAStD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAAsB,EACtB,aAAqB;IAErB,oBAAoB,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,KAAK,CACxC,mEAAmE,aAAa,GAAG,CACpF,CAAC;IAEF,MAAM,iBAAiB,GAAG,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC;IACpD,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACxF,MAAM,UAAU,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACnF,MAAM,YAAY,GAAG,MAA8E,CAAC;IAEpG,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC;QAC1F,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { Connection } from '@salesforce/core';
2
+ export type UndeployedWorkItemsResult = {
3
+ undeployedWorkitemIds: string[];
4
+ };
5
+ export type ValidateDeployResult = {
6
+ success: boolean;
7
+ errorType: string | null;
8
+ errorDetails: string | null;
9
+ };
10
+ export type DeployStageResult = {
11
+ requestId: string;
12
+ status: string;
13
+ message: string;
14
+ promotedWorkitemIds: string[];
15
+ };
16
+ /**
17
+ * GET /services/data/vXX.X/connect/devops/pipelines/{pipelineId}/stages/{stageId}/undeployedWorkitems
18
+ */
19
+ export declare function getUndeployedWorkItems(connection: Connection, pipelineId: string, stageId: string): Promise<UndeployedWorkItemsResult>;
20
+ /**
21
+ * POST /services/data/vXX.X/connect/devops/pipelines/{pipelineId}/validatePromote
22
+ */
23
+ export declare function validateDeploy(connection: Connection, pipelineId: string, workItemIds: string[], targetStageId: string): Promise<ValidateDeployResult>;
24
+ /**
25
+ * POST /services/data/vXX.X/connect/devops/pipelines/{pipelineId}/promote
26
+ * When workItemIds are provided, targets those specific items (allWorkItemsInStage: false).
27
+ * When omitted, lets Core fill IDs from undeployed/external-merge state (allWorkItemsInStage: true).
28
+ */
29
+ export declare function executeDeploy(connection: Connection, pipelineId: string, targetStageId: string, fullDeploy?: boolean, testLevel?: string, runTests?: string[], workItemIds?: string[]): Promise<DeployStageResult>;
@@ -0,0 +1,68 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * GET /services/data/vXX.X/connect/devops/pipelines/{pipelineId}/stages/{stageId}/undeployedWorkitems
18
+ */
19
+ export async function getUndeployedWorkItems(connection, pipelineId, stageId) {
20
+ const path = `/services/data/v${connection.getApiVersion()}/connect/devops/pipelines/${pipelineId}/stages/${stageId}/undeployedWorkitems`;
21
+ const response = await connection.request({ method: 'GET', url: path });
22
+ return { undeployedWorkitemIds: response.undeployedWorkitemIds ?? [] };
23
+ }
24
+ /**
25
+ * POST /services/data/vXX.X/connect/devops/pipelines/{pipelineId}/validatePromote
26
+ */
27
+ export async function validateDeploy(connection, pipelineId, workItemIds, targetStageId) {
28
+ const path = `/services/data/v${connection.getApiVersion()}/connect/devops/pipelines/${pipelineId}/validatePromote`;
29
+ const response = await connection.request({
30
+ method: 'POST',
31
+ url: path,
32
+ body: JSON.stringify({ selectedWorkItemIds: workItemIds, targetStageId }),
33
+ headers: { 'Content-Type': 'application/json' },
34
+ });
35
+ return {
36
+ success: response.success ?? true,
37
+ errorType: response.errorType ?? null,
38
+ errorDetails: response.errorDetails ?? null,
39
+ };
40
+ }
41
+ /**
42
+ * POST /services/data/vXX.X/connect/devops/pipelines/{pipelineId}/promote
43
+ * When workItemIds are provided, targets those specific items (allWorkItemsInStage: false).
44
+ * When omitted, lets Core fill IDs from undeployed/external-merge state (allWorkItemsInStage: true).
45
+ */
46
+ export async function executeDeploy(connection, pipelineId, targetStageId, fullDeploy = false, testLevel = 'Default', runTests = [], workItemIds) {
47
+ const path = `/services/data/v${connection.getApiVersion()}/connect/devops/pipelines/${pipelineId}/promote`;
48
+ const explicitIds = workItemIds && workItemIds.length > 0;
49
+ const response = await connection.request({
50
+ method: 'POST',
51
+ url: path,
52
+ body: JSON.stringify({
53
+ workitemIds: explicitIds ? workItemIds : [],
54
+ targetStageId,
55
+ allWorkItemsInStage: !explicitIds,
56
+ isCheckDeploy: false,
57
+ deployOptions: { testLevel, isFullDeploy: fullDeploy, runTests },
58
+ }),
59
+ headers: { 'Content-Type': 'application/json' },
60
+ });
61
+ return {
62
+ requestId: response.requestId ?? '',
63
+ status: response.status ?? '',
64
+ message: response.message ?? '',
65
+ promotedWorkitemIds: response.promotedWorkitemIds ?? [],
66
+ };
67
+ }
68
+ //# sourceMappingURL=deployStage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deployStage.js","sourceRoot":"","sources":["../../src/utils/deployStage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAsCH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAAsB,EACtB,UAAkB,EAClB,OAAe;IAEf,MAAM,IAAI,GAAG,mBAAmB,UAAU,CAAC,aAAa,EAAE,6BAA6B,UAAU,WAAW,OAAO,sBAAsB,CAAC;IAC1I,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAA8B,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACrG,OAAO,EAAE,qBAAqB,EAAE,QAAQ,CAAC,qBAAqB,IAAI,EAAE,EAAE,CAAC;AACzE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAAsB,EACtB,UAAkB,EAClB,WAAqB,EACrB,aAAqB;IAErB,MAAM,IAAI,GAAG,mBAAmB,UAAU,CAAC,aAAa,EAAE,6BAA6B,UAAU,kBAAkB,CAAC;IACpH,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAyB;QAChE,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,IAAI;QACT,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,mBAAmB,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC;QACzE,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;IACH,OAAO;QACL,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,IAAI;QACjC,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,IAAI;QACrC,YAAY,EAAE,QAAQ,CAAC,YAAY,IAAI,IAAI;KAC5C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAsB,EACtB,UAAkB,EAClB,aAAqB,EACrB,UAAU,GAAG,KAAK,EAClB,SAAS,GAAG,SAAS,EACrB,WAAqB,EAAE,EACvB,WAAsB;IAEtB,MAAM,IAAI,GAAG,mBAAmB,UAAU,CAAC,aAAa,EAAE,6BAA6B,UAAU,UAAU,CAAC;IAC5G,MAAM,WAAW,GAAG,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAsB;QAC7D,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,IAAI;QACT,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE;YAC3C,aAAa;YACb,mBAAmB,EAAE,CAAC,WAAW;YACjC,aAAa,EAAE,KAAK;YACpB,aAAa,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE;SACjE,CAAC;QACF,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;IACH,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,EAAE;QACnC,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,EAAE;QAC7B,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE;QAC/B,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,IAAI,EAAE;KACxD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Connection } from '@salesforce/core';
2
+ export type DetachProjectResult = {
3
+ success: boolean;
4
+ projectId: string;
5
+ pipelineId: string;
6
+ error?: string;
7
+ };
8
+ export declare function detachProject(connection: Connection, projectId: string, pipelineId: string): Promise<DetachProjectResult>;
@@ -0,0 +1,37 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { validateSalesforceId } from './soqlUtils.js';
17
+ export async function detachProject(connection, projectId, pipelineId) {
18
+ validateSalesforceId(projectId, 'project');
19
+ validateSalesforceId(pipelineId, 'pipeline');
20
+ const queryResult = await connection.query(`SELECT Id FROM DevopsProjectPipeline WHERE DevopsProjectId = '${projectId}' AND DevopsPipelineId = '${pipelineId}' LIMIT 1`);
21
+ const junction = (queryResult.records ?? [])[0];
22
+ if (!junction) {
23
+ throw new Error(`ProjectNotAttached:${projectId}:${pipelineId}`);
24
+ }
25
+ const result = await connection.sobject('DevopsProjectPipeline').delete(junction.Id);
26
+ if (result.success) {
27
+ return { success: true, projectId, pipelineId };
28
+ }
29
+ const errorMessages = result.errors?.map((e) => (typeof e === 'string' ? e : JSON.stringify(e))).join('; ');
30
+ return {
31
+ success: false,
32
+ projectId,
33
+ pipelineId,
34
+ error: errorMessages ?? 'Unknown error',
35
+ };
36
+ }
37
+ //# sourceMappingURL=detachProject.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detachProject.js","sourceRoot":"","sources":["../../src/utils/detachProject.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAStD,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAsB,EACtB,SAAiB,EACjB,UAAkB;IAElB,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC3C,oBAAoB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC7C,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,KAAK,CACxC,iEAAiE,SAAS,6BAA6B,UAAU,WAAW,CAC7H,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,IAAI,UAAU,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAErF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;IAClD,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5G,OAAO;QACL,OAAO,EAAE,KAAK;QACd,SAAS;QACT,UAAU;QACV,KAAK,EAAE,aAAa,IAAI,eAAe;KACxC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { Connection } from '@salesforce/core';
2
+ export type StageEnvironment = {
3
+ id: string;
4
+ name: string;
5
+ };
6
+ export type PipelineStageDetail = {
7
+ id: string;
8
+ name: string | null;
9
+ nextStageId: string | null;
10
+ branchName: string | null;
11
+ repositoryName: string | null;
12
+ repositoryOwner: string | null;
13
+ environment: StageEnvironment | null;
14
+ };
15
+ export type ConnectedProject = {
16
+ id: string;
17
+ name: string | null;
18
+ };
19
+ export type PipelineGetResult = {
20
+ id: string;
21
+ name: string;
22
+ description: string | null;
23
+ isActive: boolean;
24
+ stages: PipelineStageDetail[];
25
+ connectedProjects: ConnectedProject[];
26
+ };
27
+ export declare function getPipeline(connection: Connection, pipelineId: string): Promise<PipelineGetResult>;
@@ -0,0 +1,66 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { validateSalesforceId } from './soqlUtils.js';
17
+ function orderStages(stages) {
18
+ if (stages.length <= 1)
19
+ return stages;
20
+ const nextIds = new Set(stages.map((s) => s.nextStageId).filter(Boolean));
21
+ const first = stages.find((s) => !nextIds.has(s.id));
22
+ if (!first)
23
+ return stages;
24
+ const byId = new Map(stages.map((s) => [s.id, s]));
25
+ const ordered = [];
26
+ let current = first;
27
+ while (current) {
28
+ ordered.push(current);
29
+ current = current.nextStageId ? byId.get(current.nextStageId) : undefined;
30
+ }
31
+ return ordered;
32
+ }
33
+ export async function getPipeline(connection, pipelineId) {
34
+ validateSalesforceId(pipelineId, 'pipeline');
35
+ const pipelineResult = await connection.query(`SELECT Id, Name, Description, IsActive FROM DevopsPipeline WHERE Id = '${pipelineId}' LIMIT 1`);
36
+ const pipeline = (pipelineResult.records ?? [])[0];
37
+ if (!pipeline) {
38
+ throw new Error(`Pipeline not found: ${pipelineId}`);
39
+ }
40
+ const [stageResult, junctionResult] = await Promise.all([
41
+ connection.query(`SELECT Id, Name, NextStageId, DevopsPipelineId, SourceCodeRepositoryBranch.Name, SourceCodeRepositoryBranch.SourceCodeRepository.Name, SourceCodeRepositoryBranch.SourceCodeRepository.RepositoryOwner, DevOpsEnvironment.Id, DevOpsEnvironment.Name FROM DevopsPipelineStage WHERE DevopsPipelineId = '${pipelineId}'`),
42
+ connection.query(`SELECT DevopsProjectId, DevopsProject.Name FROM DevopsProjectPipeline WHERE DevopsPipelineId = '${pipelineId}'`),
43
+ ]);
44
+ const stages = orderStages((stageResult.records ?? []).map((s) => ({
45
+ id: s.Id,
46
+ name: s.Name,
47
+ nextStageId: s.NextStageId ?? null,
48
+ branchName: s.SourceCodeRepositoryBranch?.Name ?? null,
49
+ repositoryName: s.SourceCodeRepositoryBranch?.SourceCodeRepository?.Name ?? null,
50
+ repositoryOwner: s.SourceCodeRepositoryBranch?.SourceCodeRepository?.RepositoryOwner ?? null,
51
+ environment: s.DevOpsEnvironment ? { id: s.DevOpsEnvironment.Id, name: s.DevOpsEnvironment.Name } : null,
52
+ })));
53
+ const connectedProjects = (junctionResult.records ?? []).map((j) => ({
54
+ id: j.DevopsProjectId,
55
+ name: j.DevopsProject?.Name ?? null,
56
+ }));
57
+ return {
58
+ id: pipeline.Id,
59
+ name: pipeline.Name,
60
+ description: pipeline.Description,
61
+ isActive: pipeline.IsActive,
62
+ stages,
63
+ connectedProjects,
64
+ };
65
+ }
66
+ //# sourceMappingURL=getPipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getPipeline.js","sourceRoot":"","sources":["../../src/utils/getPipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { Connection } from '@salesforce/core';
2
+ export type RequestStatusResult = {
3
+ id: string;
4
+ status: string;
5
+ message: string | null;
6
+ errorDetails: string | null;
7
+ requestToken: string;
8
+ requestCompletionDate: string | null;
9
+ };
10
+ export declare function getRequestStatus(connection: Connection, requestToken: string): Promise<RequestStatusResult>;
@@ -0,0 +1,32 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { escapeSOQL } from './soqlUtils.js';
17
+ export async function getRequestStatus(connection, requestToken) {
18
+ const result = await connection.query(`SELECT Id, Status, Message, ErrorDetails, RequestToken, RequestCompletionDate FROM DevopsRequestInfo WHERE RequestToken = '${escapeSOQL(requestToken)}' LIMIT 1`);
19
+ const record = (result.records ?? [])[0];
20
+ if (!record) {
21
+ throw new Error(`RequestNotFound:${requestToken}`);
22
+ }
23
+ return {
24
+ id: record.Id,
25
+ status: record.Status,
26
+ message: record.Message,
27
+ errorDetails: record.ErrorDetails,
28
+ requestToken: record.RequestToken,
29
+ requestCompletionDate: record.RequestCompletionDate,
30
+ };
31
+ }
32
+ //# sourceMappingURL=getRequestStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getRequestStatus.js","sourceRoot":"","sources":["../../src/utils/getRequestStatus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAoB5C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,UAAsB,EAAE,YAAoB;IACjF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CACnC,8HAA8H,UAAU,CACtI,YAAY,CACb,WAAW,CACb,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;KACpD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Connection } from '@salesforce/core';
2
+ export type DevopsPipeline = {
3
+ Id: string;
4
+ Name: string;
5
+ Description: string | null;
6
+ IsActive: boolean;
7
+ };
8
+ export type PipelineListResult = {
9
+ pipelines: DevopsPipeline[];
10
+ };
11
+ export declare function listPipelines(connection: Connection): Promise<PipelineListResult>;
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ export async function listPipelines(connection) {
17
+ const result = await connection.query('SELECT Id, Name, Description, IsActive FROM DevopsPipeline');
18
+ return { pipelines: result.records ?? [] };
19
+ }
20
+ //# sourceMappingURL=listPipelines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listPipelines.js","sourceRoot":"","sources":["../../src/utils/listPipelines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAeH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAsB;IACxD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAiB,4DAA4D,CAAC,CAAC;IACpH,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;AAC7C,CAAC"}
@@ -13,12 +13,15 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { validateSalesforceId } from './soqlUtils.js';
16
17
  export async function getPipelineIdForProject(connection, projectId) {
18
+ validateSalesforceId(projectId, 'project');
17
19
  const query = `SELECT DevopsPipelineId FROM DevopsProjectPipeline WHERE DevopsProjectId = '${projectId}' LIMIT 1`;
18
20
  const result = await connection.query(query);
19
21
  return (result.records ?? [])[0]?.DevopsPipelineId;
20
22
  }
21
23
  export async function fetchPipelineStages(connection, pipelineId) {
24
+ validateSalesforceId(pipelineId, 'pipeline');
22
25
  const stageQuery = `SELECT Id, Name, NextStageId, SourceCodeRepositoryBranch.Name FROM DevopsPipelineStage WHERE DevopsPipelineId = '${pipelineId}'`;
23
26
  const stageResult = await connection.query(stageQuery);
24
27
  return stageResult.records ?? [];
@@ -1 +1 @@
1
- {"version":3,"file":"pipelineUtils.js","sourceRoot":"","sources":["../../src/utils/pipelineUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,UAAsB,EAAE,SAAiB;IACrF,MAAM,KAAK,GAAG,+EAA+E,SAAS,WAAW,CAAC;IAClH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAmC,KAAK,CAAC,CAAC;IAC/E,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAAsB,EAAE,UAAkB;IAClF,MAAM,UAAU,GAAG,oHAAoH,UAAU,GAAG,CAAC;IACrJ,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,KAAK,CAAsB,UAAU,CAAC,CAAC;IAC5E,OAAO,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAA6B;IAC/D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC,CAAC;IACnG,MAAM,aAAa,GAAa,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9F,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,cAAkC,EAClC,MAA6B;IAE7B,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACrC,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC,CAAC;QAC5D,OAAO,OAAO,EAAE,WAAW,IAAI,SAAS,CAAC;IAC3C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,MAA6B,EAC7B,OAA2B;IAE3B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAsC;IAC3E,OAAO,KAAK,EAAE,0BAA0B,EAAE,IAAI,IAAI,SAAS,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"pipelineUtils.js","sourceRoot":"","sources":["../../src/utils/pipelineUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,UAAsB,EAAE,SAAiB;IACrF,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,+EAA+E,SAAS,WAAW,CAAC;IAClH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAmC,KAAK,CAAC,CAAC;IAC/E,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAAsB,EAAE,UAAkB;IAClF,oBAAoB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,oHAAoH,UAAU,GAAG,CAAC;IACrJ,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,KAAK,CAAsB,UAAU,CAAC,CAAC;IAC5E,OAAO,WAAW,CAAC,OAAO,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAA6B;IAC/D,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC,CAAC;IACnG,MAAM,aAAa,GAAa,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9F,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,cAAkC,EAClC,MAA6B;IAE7B,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACrC,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,cAAc,CAAC,CAAC;QAC5D,OAAO,OAAO,EAAE,WAAW,IAAI,SAAS,CAAC;IAC3C,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,MAA6B,EAC7B,OAA2B;IAE3B,IAAI,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IAC/B,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAsC;IAC3E,OAAO,KAAK,EAAE,0BAA0B,EAAE,IAAI,IAAI,SAAS,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { Connection } from '@salesforce/core';
2
+ export type PrepareWorkItemParams = {
3
+ connection: Connection;
4
+ pipelineId: string;
5
+ workItemId: string;
6
+ sourceStageId: string;
7
+ targetStageId: string;
8
+ };
9
+ export type PrepareWorkItemResult = {
10
+ success: boolean;
11
+ requestToken: string | null;
12
+ errorCode: string | null;
13
+ errorMessage: string | null;
14
+ };
15
+ /**
16
+ * Prepares a work item for one-off promotion by creating the necessary branches
17
+ * and pull requests in the source control repository.
18
+ * API: POST /services/data/v{version}/connect/devops/pipelines/{pipelineId}/promote/oneoff/prepare
19
+ */
20
+ export declare function prepareWorkItem(params: PrepareWorkItemParams): Promise<PrepareWorkItemResult>;
21
+ export type WorkItemContext = {
22
+ projectId: string;
23
+ pipelineStageId: string;
24
+ };
25
+ export declare function resolveProjectIdFromWorkItem(connection: Connection, workItemId: string): Promise<WorkItemContext>;
@@ -0,0 +1,55 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { validateSalesforceId } from './soqlUtils.js';
17
+ /**
18
+ * Prepares a work item for one-off promotion by creating the necessary branches
19
+ * and pull requests in the source control repository.
20
+ * API: POST /services/data/v{version}/connect/devops/pipelines/{pipelineId}/promote/oneoff/prepare
21
+ */
22
+ export async function prepareWorkItem(params) {
23
+ const { connection, pipelineId, workItemId, sourceStageId, targetStageId } = params;
24
+ const path = `/services/data/v${connection.getApiVersion()}/connect/devops/pipelines/${pipelineId}/promote/oneoff/prepare`;
25
+ const body = JSON.stringify({
26
+ selectedWorkItemId: workItemId,
27
+ sourceStageId,
28
+ targetStageId,
29
+ });
30
+ const data = await connection.request({
31
+ method: 'POST',
32
+ url: path,
33
+ body,
34
+ headers: { 'Content-Type': 'application/json' },
35
+ });
36
+ return {
37
+ success: data.success ?? true,
38
+ requestToken: data.requestToken ?? null,
39
+ errorCode: data.errorCode ?? null,
40
+ errorMessage: data.errorMessage ?? null,
41
+ };
42
+ }
43
+ export async function resolveProjectIdFromWorkItem(connection, workItemId) {
44
+ validateSalesforceId(workItemId, 'work item');
45
+ const result = await connection.query(`SELECT DevopsProjectId, DevopsPipelineStageId FROM WorkItem WHERE Id = '${workItemId}' LIMIT 1`);
46
+ const records = result.records ?? [];
47
+ if (records.length === 0) {
48
+ throw new Error(`Work item '${workItemId}' not found. Verify the work item ID and try again.`);
49
+ }
50
+ return {
51
+ projectId: records[0].DevopsProjectId,
52
+ pipelineStageId: records[0].DevopsPipelineStageId ?? '',
53
+ };
54
+ }
55
+ //# sourceMappingURL=prepareWorkItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepareWorkItem.js","sourceRoot":"","sources":["../../src/utils/prepareWorkItem.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAwBtD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,MAA6B;IACjE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,MAAM,CAAC;IAEpF,MAAM,IAAI,GAAG,mBAAmB,UAAU,CAAC,aAAa,EAAE,6BAA6B,UAAU,yBAAyB,CAAC;IAC3H,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC;QAC1B,kBAAkB,EAAE,UAAU;QAC9B,aAAa;QACb,aAAa;KACd,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,OAAO,CAAiC;QACpE,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,IAAI;QACT,IAAI;QACJ,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;QAC7B,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;QACvC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;QACjC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;KACxC,CAAC;AACJ,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,UAAsB,EACtB,UAAkB;IAElB,oBAAoB,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CACnC,2EAA2E,UAAU,WAAW,CACjG,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;IACrC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,cAAc,UAAU,qDAAqD,CAAC,CAAC;IACjG,CAAC;IACD,OAAO;QACL,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe;QACrC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,qBAAqB,IAAI,EAAE;KACxD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { Connection } from '@salesforce/core';
2
+ export type PromoteStageParams = {
3
+ connection: Connection;
4
+ pipelineId: string;
5
+ workItemIds: string[];
6
+ targetStageId: string;
7
+ fullDeploy?: boolean;
8
+ testLevel?: string;
9
+ runTests?: string[];
10
+ };
11
+ export type PromoteStageResult = {
12
+ requestId: string;
13
+ status: string;
14
+ message: string;
15
+ promotedWorkitemIds: string[];
16
+ };
17
+ /**
18
+ * Promotes work items to a target pipeline stage via the Connect API.
19
+ * POST /services/data/v{version}/connect/devops/pipelines/{pipelineId}/promote
20
+ */
21
+ export declare function promoteStage(params: PromoteStageParams): Promise<PromoteStageResult>;
@@ -0,0 +1,46 @@
1
+ /*
2
+ * Copyright 2026, Salesforce, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * Promotes work items to a target pipeline stage via the Connect API.
18
+ * POST /services/data/v{version}/connect/devops/pipelines/{pipelineId}/promote
19
+ */
20
+ export async function promoteStage(params) {
21
+ const { connection, pipelineId, workItemIds, targetStageId, fullDeploy = false, testLevel = 'Default', runTests, } = params;
22
+ const path = `/services/data/v${connection.getApiVersion()}/connect/devops/pipelines/${pipelineId}/promote`;
23
+ const response = await connection.request({
24
+ method: 'POST',
25
+ url: path,
26
+ body: JSON.stringify({
27
+ workitemIds: workItemIds,
28
+ targetStageId,
29
+ allWorkItemsInStage: false,
30
+ isCheckDeploy: false,
31
+ deployOptions: {
32
+ testLevel,
33
+ isFullDeploy: fullDeploy,
34
+ runTests: runTests ?? [],
35
+ },
36
+ }),
37
+ headers: { 'Content-Type': 'application/json' },
38
+ });
39
+ return {
40
+ requestId: response.requestId ?? '',
41
+ status: response.status ?? '',
42
+ message: response.message ?? '',
43
+ promotedWorkitemIds: response.promotedWorkitemIds ?? [],
44
+ };
45
+ }
46
+ //# sourceMappingURL=promoteStage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promoteStage.js","sourceRoot":"","sources":["../../src/utils/promoteStage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AA4BH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAA0B;IAC3D,MAAM,EACJ,UAAU,EACV,UAAU,EACV,WAAW,EACX,aAAa,EACb,UAAU,GAAG,KAAK,EAClB,SAAS,GAAG,SAAS,EACrB,QAAQ,GACT,GAAG,MAAM,CAAC;IAEX,MAAM,IAAI,GAAG,mBAAmB,UAAU,CAAC,aAAa,EAAE,6BAA6B,UAAU,UAAU,CAAC;IAE5G,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAuB;QAC9D,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,IAAI;QACT,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,WAAW,EAAE,WAAW;YACxB,aAAa;YACb,mBAAmB,EAAE,KAAK;YAC1B,aAAa,EAAE,KAAK;YACpB,aAAa,EAAE;gBACb,SAAS;gBACT,YAAY,EAAE,UAAU;gBACxB,QAAQ,EAAE,QAAQ,IAAI,EAAE;aACzB;SACF,CAAC;QACF,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAC;IAEH,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,SAAS,IAAI,EAAE;QACnC,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,EAAE;QAC7B,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE;QAC/B,mBAAmB,EAAE,QAAQ,CAAC,mBAAmB,IAAI,EAAE;KACxD,CAAC;AACJ,CAAC"}