@pax8-cta/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/LICENSE +198 -0
  2. package/dist/auth/device-code-login.d.ts +40 -0
  3. package/dist/auth/device-code-login.d.ts.map +1 -0
  4. package/dist/auth/device-code-login.js +59 -0
  5. package/dist/auth/device-code-login.js.map +1 -0
  6. package/dist/auth/gdap-client.d.ts +81 -0
  7. package/dist/auth/gdap-client.d.ts.map +1 -0
  8. package/dist/auth/gdap-client.js +128 -0
  9. package/dist/auth/gdap-client.js.map +1 -0
  10. package/dist/auth/index.d.ts +19 -0
  11. package/dist/auth/index.d.ts.map +1 -0
  12. package/dist/auth/index.js +19 -0
  13. package/dist/auth/index.js.map +1 -0
  14. package/dist/auth/token-manager.d.ts +54 -0
  15. package/dist/auth/token-manager.d.ts.map +1 -0
  16. package/dist/auth/token-manager.js +150 -0
  17. package/dist/auth/token-manager.js.map +1 -0
  18. package/dist/client.d.ts +27 -0
  19. package/dist/client.d.ts.map +1 -0
  20. package/dist/client.js +27 -0
  21. package/dist/client.js.map +1 -0
  22. package/dist/config/client.d.ts +24 -0
  23. package/dist/config/client.d.ts.map +1 -0
  24. package/dist/config/client.js +18 -0
  25. package/dist/config/client.js.map +1 -0
  26. package/dist/config/index.d.ts +18 -0
  27. package/dist/config/index.d.ts.map +1 -0
  28. package/dist/config/index.js +18 -0
  29. package/dist/config/index.js.map +1 -0
  30. package/dist/config/loader.d.ts +81 -0
  31. package/dist/config/loader.d.ts.map +1 -0
  32. package/dist/config/loader.js +271 -0
  33. package/dist/config/loader.js.map +1 -0
  34. package/dist/config/schema.d.ts +751 -0
  35. package/dist/config/schema.d.ts.map +1 -0
  36. package/dist/config/schema.js +556 -0
  37. package/dist/config/schema.js.map +1 -0
  38. package/dist/constants.d.ts +116 -0
  39. package/dist/constants.d.ts.map +1 -0
  40. package/dist/constants.js +170 -0
  41. package/dist/constants.js.map +1 -0
  42. package/dist/dataverse/agent-resolver.d.ts +98 -0
  43. package/dist/dataverse/agent-resolver.d.ts.map +1 -0
  44. package/dist/dataverse/agent-resolver.js +185 -0
  45. package/dist/dataverse/agent-resolver.js.map +1 -0
  46. package/dist/dataverse/client.d.ts +104 -0
  47. package/dist/dataverse/client.d.ts.map +1 -0
  48. package/dist/dataverse/client.js +272 -0
  49. package/dist/dataverse/client.js.map +1 -0
  50. package/dist/dataverse/connection-refs.d.ts +115 -0
  51. package/dist/dataverse/connection-refs.d.ts.map +1 -0
  52. package/dist/dataverse/connection-refs.js +203 -0
  53. package/dist/dataverse/connection-refs.js.map +1 -0
  54. package/dist/dataverse/index.d.ts +20 -0
  55. package/dist/dataverse/index.d.ts.map +1 -0
  56. package/dist/dataverse/index.js +20 -0
  57. package/dist/dataverse/index.js.map +1 -0
  58. package/dist/dataverse/solution-ops.d.ts +100 -0
  59. package/dist/dataverse/solution-ops.d.ts.map +1 -0
  60. package/dist/dataverse/solution-ops.js +288 -0
  61. package/dist/dataverse/solution-ops.js.map +1 -0
  62. package/dist/errors.d.ts +171 -0
  63. package/dist/errors.d.ts.map +1 -0
  64. package/dist/errors.js +178 -0
  65. package/dist/errors.js.map +1 -0
  66. package/dist/index.d.ts +27 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +40 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/mock/demo-data.d.ts +213 -0
  71. package/dist/mock/demo-data.d.ts.map +1 -0
  72. package/dist/mock/demo-data.js +1096 -0
  73. package/dist/mock/demo-data.js.map +1 -0
  74. package/dist/mock/demo-deployment-store.d.ts +77 -0
  75. package/dist/mock/demo-deployment-store.d.ts.map +1 -0
  76. package/dist/mock/demo-deployment-store.js +85 -0
  77. package/dist/mock/demo-deployment-store.js.map +1 -0
  78. package/dist/powerplatform/admin-client.d.ts +226 -0
  79. package/dist/powerplatform/admin-client.d.ts.map +1 -0
  80. package/dist/powerplatform/admin-client.js +315 -0
  81. package/dist/powerplatform/admin-client.js.map +1 -0
  82. package/dist/powerplatform/index.d.ts +18 -0
  83. package/dist/powerplatform/index.d.ts.map +1 -0
  84. package/dist/powerplatform/index.js +18 -0
  85. package/dist/powerplatform/index.js.map +1 -0
  86. package/dist/powerplatform/tenant-discovery.d.ts +100 -0
  87. package/dist/powerplatform/tenant-discovery.d.ts.map +1 -0
  88. package/dist/powerplatform/tenant-discovery.js +205 -0
  89. package/dist/powerplatform/tenant-discovery.js.map +1 -0
  90. package/dist/preconditions/check.d.ts +41 -0
  91. package/dist/preconditions/check.d.ts.map +1 -0
  92. package/dist/preconditions/check.js +173 -0
  93. package/dist/preconditions/check.js.map +1 -0
  94. package/dist/preconditions/index.d.ts +20 -0
  95. package/dist/preconditions/index.d.ts.map +1 -0
  96. package/dist/preconditions/index.js +20 -0
  97. package/dist/preconditions/index.js.map +1 -0
  98. package/dist/preconditions/loader.d.ts +33 -0
  99. package/dist/preconditions/loader.d.ts.map +1 -0
  100. package/dist/preconditions/loader.js +65 -0
  101. package/dist/preconditions/loader.js.map +1 -0
  102. package/dist/preconditions/schema.d.ts +103 -0
  103. package/dist/preconditions/schema.d.ts.map +1 -0
  104. package/dist/preconditions/schema.js +93 -0
  105. package/dist/preconditions/schema.js.map +1 -0
  106. package/dist/preconditions/types.d.ts +118 -0
  107. package/dist/preconditions/types.d.ts.map +1 -0
  108. package/dist/preconditions/types.js +17 -0
  109. package/dist/preconditions/types.js.map +1 -0
  110. package/dist/queue/index.d.ts +17 -0
  111. package/dist/queue/index.d.ts.map +1 -0
  112. package/dist/queue/index.js +17 -0
  113. package/dist/queue/index.js.map +1 -0
  114. package/dist/queue/memory-queue.d.ts +86 -0
  115. package/dist/queue/memory-queue.d.ts.map +1 -0
  116. package/dist/queue/memory-queue.js +221 -0
  117. package/dist/queue/memory-queue.js.map +1 -0
  118. package/dist/services/audit-log.d.ts +59 -0
  119. package/dist/services/audit-log.d.ts.map +1 -0
  120. package/dist/services/audit-log.js +193 -0
  121. package/dist/services/audit-log.js.map +1 -0
  122. package/dist/services/auth-error-parser.d.ts +36 -0
  123. package/dist/services/auth-error-parser.d.ts.map +1 -0
  124. package/dist/services/auth-error-parser.js +90 -0
  125. package/dist/services/auth-error-parser.js.map +1 -0
  126. package/dist/services/deployment-doctor.d.ts +109 -0
  127. package/dist/services/deployment-doctor.d.ts.map +1 -0
  128. package/dist/services/deployment-doctor.js +476 -0
  129. package/dist/services/deployment-doctor.js.map +1 -0
  130. package/dist/services/deployment-notifications.d.ts +41 -0
  131. package/dist/services/deployment-notifications.d.ts.map +1 -0
  132. package/dist/services/deployment-notifications.js +161 -0
  133. package/dist/services/deployment-notifications.js.map +1 -0
  134. package/dist/services/deployment-progress.d.ts +89 -0
  135. package/dist/services/deployment-progress.d.ts.map +1 -0
  136. package/dist/services/deployment-progress.js +244 -0
  137. package/dist/services/deployment-progress.js.map +1 -0
  138. package/dist/services/deployment-service.d.ts +97 -0
  139. package/dist/services/deployment-service.d.ts.map +1 -0
  140. package/dist/services/deployment-service.js +375 -0
  141. package/dist/services/deployment-service.js.map +1 -0
  142. package/dist/services/drift-analyzer.d.ts +86 -0
  143. package/dist/services/drift-analyzer.d.ts.map +1 -0
  144. package/dist/services/drift-analyzer.js +273 -0
  145. package/dist/services/drift-analyzer.js.map +1 -0
  146. package/dist/services/environment-setup.d.ts +97 -0
  147. package/dist/services/environment-setup.d.ts.map +1 -0
  148. package/dist/services/environment-setup.js +250 -0
  149. package/dist/services/environment-setup.js.map +1 -0
  150. package/dist/services/health-check.d.ts +168 -0
  151. package/dist/services/health-check.d.ts.map +1 -0
  152. package/dist/services/health-check.js +705 -0
  153. package/dist/services/health-check.js.map +1 -0
  154. package/dist/services/index.d.ts +39 -0
  155. package/dist/services/index.d.ts.map +1 -0
  156. package/dist/services/index.js +39 -0
  157. package/dist/services/index.js.map +1 -0
  158. package/dist/services/logger.d.ts +139 -0
  159. package/dist/services/logger.d.ts.map +1 -0
  160. package/dist/services/logger.js +268 -0
  161. package/dist/services/logger.js.map +1 -0
  162. package/dist/services/notification-service.d.ts +55 -0
  163. package/dist/services/notification-service.d.ts.map +1 -0
  164. package/dist/services/notification-service.js +184 -0
  165. package/dist/services/notification-service.js.map +1 -0
  166. package/dist/services/risk-analyzer.d.ts +252 -0
  167. package/dist/services/risk-analyzer.d.ts.map +1 -0
  168. package/dist/services/risk-analyzer.js +866 -0
  169. package/dist/services/risk-analyzer.js.map +1 -0
  170. package/dist/services/rollback.d.ts +57 -0
  171. package/dist/services/rollback.d.ts.map +1 -0
  172. package/dist/services/rollback.js +270 -0
  173. package/dist/services/rollback.js.map +1 -0
  174. package/dist/services/scheduler.d.ts +80 -0
  175. package/dist/services/scheduler.d.ts.map +1 -0
  176. package/dist/services/scheduler.js +350 -0
  177. package/dist/services/scheduler.js.map +1 -0
  178. package/dist/services/secrets.d.ts +31 -0
  179. package/dist/services/secrets.d.ts.map +1 -0
  180. package/dist/services/secrets.js +206 -0
  181. package/dist/services/secrets.js.map +1 -0
  182. package/dist/services/settings-service.d.ts +132 -0
  183. package/dist/services/settings-service.d.ts.map +1 -0
  184. package/dist/services/settings-service.js +378 -0
  185. package/dist/services/settings-service.js.map +1 -0
  186. package/dist/services/solution-diff.d.ts +127 -0
  187. package/dist/services/solution-diff.d.ts.map +1 -0
  188. package/dist/services/solution-diff.js +260 -0
  189. package/dist/services/solution-diff.js.map +1 -0
  190. package/dist/services/solution-mode-detector.d.ts +35 -0
  191. package/dist/services/solution-mode-detector.d.ts.map +1 -0
  192. package/dist/services/solution-mode-detector.js +84 -0
  193. package/dist/services/solution-mode-detector.js.map +1 -0
  194. package/dist/services/tenant-resolver.d.ts +55 -0
  195. package/dist/services/tenant-resolver.d.ts.map +1 -0
  196. package/dist/services/tenant-resolver.js +126 -0
  197. package/dist/services/tenant-resolver.js.map +1 -0
  198. package/dist/services/unmanaged-customizations.d.ts +104 -0
  199. package/dist/services/unmanaged-customizations.d.ts.map +1 -0
  200. package/dist/services/unmanaged-customizations.js +521 -0
  201. package/dist/services/unmanaged-customizations.js.map +1 -0
  202. package/dist/services/url-templater.d.ts +184 -0
  203. package/dist/services/url-templater.d.ts.map +1 -0
  204. package/dist/services/url-templater.js +327 -0
  205. package/dist/services/url-templater.js.map +1 -0
  206. package/dist/services/version-checker.d.ts +108 -0
  207. package/dist/services/version-checker.d.ts.map +1 -0
  208. package/dist/services/version-checker.js +403 -0
  209. package/dist/services/version-checker.js.map +1 -0
  210. package/dist/services/waves.d.ts +90 -0
  211. package/dist/services/waves.d.ts.map +1 -0
  212. package/dist/services/waves.js +222 -0
  213. package/dist/services/waves.js.map +1 -0
  214. package/dist/services/webhook.d.ts +95 -0
  215. package/dist/services/webhook.d.ts.map +1 -0
  216. package/dist/services/webhook.js +244 -0
  217. package/dist/services/webhook.js.map +1 -0
  218. package/dist/utils/deployment-tools.d.ts +110 -0
  219. package/dist/utils/deployment-tools.d.ts.map +1 -0
  220. package/dist/utils/deployment-tools.js +121 -0
  221. package/dist/utils/deployment-tools.js.map +1 -0
  222. package/dist/utils/index.d.ts +17 -0
  223. package/dist/utils/index.d.ts.map +1 -0
  224. package/dist/utils/index.js +18 -0
  225. package/dist/utils/index.js.map +1 -0
  226. package/package.json +49 -0
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Copyright 2024 Pax8, 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 { parseDuration } from "../config/schema.js";
17
+ /**
18
+ * Service for managing deployment waves
19
+ */
20
+ export class WaveService {
21
+ /**
22
+ * Create an execution plan from configuration
23
+ */
24
+ createExecutionPlan(config, selectedTenants) {
25
+ const waves = config.settings?.waves;
26
+ const tenants = selectedTenants || config.tenants.filter((t) => t.enabled);
27
+ // If no waves configured, put all tenants in a single wave
28
+ if (!waves || waves.length === 0) {
29
+ return {
30
+ waves: [
31
+ {
32
+ waveNumber: 1,
33
+ name: "Default",
34
+ tenants,
35
+ continueOnFailure: false,
36
+ },
37
+ ],
38
+ totalTenants: tenants.length,
39
+ };
40
+ }
41
+ // Sort waves by order
42
+ const sortedWaves = [...waves].sort((a, b) => a.order - b.order);
43
+ // Assign tenants to waves
44
+ const assignedTenants = new Set();
45
+ const executionWaves = [];
46
+ for (const wave of sortedWaves) {
47
+ const waveTenants = [];
48
+ for (const tenant of tenants) {
49
+ // Skip if already assigned
50
+ if (assignedTenants.has(tenant.tenantId))
51
+ continue;
52
+ // Check if tenant matches wave criteria (by name or tag)
53
+ const matchesByName = wave.tenants.includes(tenant.name);
54
+ const matchesByTag = wave.tenants.some((wt) => tenant.tags?.includes(wt));
55
+ const matchesByTenantId = wave.tenants.includes(tenant.tenantId);
56
+ if (matchesByName || matchesByTag || matchesByTenantId) {
57
+ waveTenants.push(tenant);
58
+ assignedTenants.add(tenant.tenantId);
59
+ }
60
+ }
61
+ if (waveTenants.length > 0) {
62
+ executionWaves.push({
63
+ waveNumber: wave.order,
64
+ name: wave.name,
65
+ tenants: waveTenants,
66
+ maxParallel: wave.maxParallel,
67
+ waitAfterCompletion: wave.waitAfterCompletion
68
+ ? parseDuration(wave.waitAfterCompletion)
69
+ : undefined,
70
+ continueOnFailure: wave.continueOnFailure ?? false,
71
+ });
72
+ }
73
+ }
74
+ // Put remaining tenants in an "Unassigned" wave at the end
75
+ const unassignedTenants = tenants.filter((t) => !assignedTenants.has(t.tenantId));
76
+ if (unassignedTenants.length > 0) {
77
+ const maxWaveNumber = Math.max(...executionWaves.map((w) => w.waveNumber), 0);
78
+ executionWaves.push({
79
+ waveNumber: maxWaveNumber + 1,
80
+ name: "Unassigned",
81
+ tenants: unassignedTenants,
82
+ continueOnFailure: false,
83
+ });
84
+ }
85
+ return {
86
+ waves: executionWaves,
87
+ totalTenants: tenants.length,
88
+ };
89
+ }
90
+ /**
91
+ * Get tenants with wave assignments
92
+ */
93
+ getTenantsWithWaves(plan) {
94
+ const result = [];
95
+ for (const wave of plan.waves) {
96
+ for (const tenant of wave.tenants) {
97
+ result.push({
98
+ ...tenant,
99
+ waveNumber: wave.waveNumber,
100
+ waveName: wave.name,
101
+ });
102
+ }
103
+ }
104
+ return result;
105
+ }
106
+ /**
107
+ * Calculate estimated deployment time based on waves
108
+ */
109
+ estimateDeploymentTime(plan, avgTenantDeploymentMs = 60000 // Default: 1 minute per tenant
110
+ ) {
111
+ const waveEstimates = [];
112
+ let totalMs = 0;
113
+ for (const wave of plan.waves) {
114
+ // Time for this wave depends on maxParallel
115
+ const parallel = wave.maxParallel || wave.tenants.length;
116
+ const batches = Math.ceil(wave.tenants.length / parallel);
117
+ const waveTime = batches * avgTenantDeploymentMs;
118
+ // Add wait time after wave
119
+ const totalWaveTime = waveTime + (wave.waitAfterCompletion || 0);
120
+ waveEstimates.push({
121
+ waveNumber: wave.waveNumber,
122
+ name: wave.name,
123
+ estimatedMs: totalWaveTime,
124
+ });
125
+ totalMs += totalWaveTime;
126
+ }
127
+ return {
128
+ totalEstimatedMs: totalMs,
129
+ waveEstimates,
130
+ };
131
+ }
132
+ /**
133
+ * Validate wave configuration
134
+ */
135
+ validateWaveConfig(config) {
136
+ const errors = [];
137
+ const warnings = [];
138
+ const waves = config.settings?.waves || [];
139
+ if (waves.length === 0) {
140
+ return { valid: true, errors: [], warnings: [] };
141
+ }
142
+ // Check for duplicate wave orders
143
+ const orders = waves.map((w) => w.order);
144
+ const uniqueOrders = new Set(orders);
145
+ if (orders.length !== uniqueOrders.size) {
146
+ errors.push("Duplicate wave order numbers found");
147
+ }
148
+ // Check for duplicate wave names
149
+ const names = waves.map((w) => w.name);
150
+ const uniqueNames = new Set(names);
151
+ if (names.length !== uniqueNames.size) {
152
+ errors.push("Duplicate wave names found");
153
+ }
154
+ // Check if all referenced tenants exist
155
+ const tenantIds = new Set(config.tenants.map((t) => t.tenantId));
156
+ const tenantNames = new Set(config.tenants.map((t) => t.name));
157
+ const tenantTags = new Set(config.tenants.flatMap((t) => t.tags || []));
158
+ for (const wave of waves) {
159
+ for (const ref of wave.tenants) {
160
+ const matchesTenantId = tenantIds.has(ref);
161
+ const matchesTenantName = tenantNames.has(ref);
162
+ const matchesTag = tenantTags.has(ref);
163
+ if (!matchesTenantId && !matchesTenantName && !matchesTag) {
164
+ warnings.push(`Wave "${wave.name}" references unknown tenant/tag: "${ref}"`);
165
+ }
166
+ }
167
+ }
168
+ // Check for overlapping tenant assignments
169
+ const assignedTenants = new Map();
170
+ for (const wave of waves) {
171
+ for (const tenant of config.tenants) {
172
+ const matchesByName = wave.tenants.includes(tenant.name);
173
+ const matchesByTag = wave.tenants.some((wt) => tenant.tags?.includes(wt));
174
+ const matchesByTenantId = wave.tenants.includes(tenant.tenantId);
175
+ if (matchesByName || matchesByTag || matchesByTenantId) {
176
+ const existing = assignedTenants.get(tenant.tenantId) || [];
177
+ existing.push(wave.name);
178
+ assignedTenants.set(tenant.tenantId, existing);
179
+ }
180
+ }
181
+ }
182
+ for (const [tenantId, waveNames] of assignedTenants) {
183
+ if (waveNames.length > 1) {
184
+ const tenant = config.tenants.find((t) => t.tenantId === tenantId);
185
+ warnings.push(`Tenant "${tenant?.name}" matches multiple waves: ${waveNames.join(", ")}. First match will be used.`);
186
+ }
187
+ }
188
+ return {
189
+ valid: errors.length === 0,
190
+ errors,
191
+ warnings,
192
+ };
193
+ }
194
+ /**
195
+ * Preview wave assignments without executing
196
+ */
197
+ previewWaves(config) {
198
+ const plan = this.createExecutionPlan(config);
199
+ const waves = plan.waves.map((wave) => ({
200
+ waveNumber: wave.waveNumber,
201
+ name: wave.name,
202
+ tenantCount: wave.tenants.length,
203
+ tenants: wave.tenants.map((t) => ({
204
+ name: t.name,
205
+ tenantId: t.tenantId,
206
+ tags: t.tags || [],
207
+ })),
208
+ }));
209
+ // Find tenants in the "Unassigned" wave
210
+ const unassignedWave = plan.waves.find((w) => w.name === "Unassigned");
211
+ const unassignedTenants = (unassignedWave?.tenants || []).map((t) => ({
212
+ name: t.name,
213
+ tenantId: t.tenantId,
214
+ tags: t.tags || [],
215
+ }));
216
+ return {
217
+ waves: waves.filter((w) => w.name !== "Unassigned"),
218
+ unassignedTenants,
219
+ };
220
+ }
221
+ }
222
+ //# sourceMappingURL=waves.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waves.js","sourceRoot":"","sources":["../../src/services/waves.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Copyright 2024 Pax8, 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 { Webhook, WebhookEvent } from "../config/schema.js";
17
+ /**
18
+ * Webhook event types
19
+ */
20
+ export type WebhookEventType = "deployment.started" | "deployment.completed" | "deployment.failed" | "wave.started" | "wave.completed" | "tenant.started" | "tenant.completed" | "tenant.failed" | "rollback.started" | "rollback.completed";
21
+ /**
22
+ * Service for sending webhook notifications
23
+ */
24
+ export declare class WebhookService {
25
+ private webhooks;
26
+ constructor(webhooks?: Webhook[]);
27
+ /**
28
+ * Add a webhook configuration
29
+ */
30
+ addWebhook(webhook: Webhook): void;
31
+ /**
32
+ * Remove a webhook by URL
33
+ */
34
+ removeWebhook(url: string): void;
35
+ /**
36
+ * Send a webhook notification for an event
37
+ */
38
+ sendNotification(eventType: WebhookEventType, payload: Omit<WebhookEvent, "event" | "timestamp">): Promise<{
39
+ sent: number;
40
+ failed: number;
41
+ errors: {
42
+ url: string;
43
+ error: string;
44
+ }[];
45
+ }>;
46
+ /**
47
+ * Send event to a specific webhook with retry logic
48
+ */
49
+ private sendToWebhook;
50
+ /**
51
+ * Generate HMAC-SHA256 signature for webhook payload
52
+ */
53
+ private generateSignature;
54
+ /**
55
+ * Helper to send deployment started notification
56
+ */
57
+ notifyDeploymentStarted(deploymentId: string, solutionName: string, totalTenants: number): Promise<void>;
58
+ /**
59
+ * Helper to send deployment completed notification
60
+ */
61
+ notifyDeploymentCompleted(deploymentId: string, solutionName: string, successCount: number, failedCount: number): Promise<void>;
62
+ /**
63
+ * Helper to send deployment failed notification
64
+ */
65
+ notifyDeploymentFailed(deploymentId: string, solutionName: string, error: string): Promise<void>;
66
+ /**
67
+ * Helper to send wave started notification
68
+ */
69
+ notifyWaveStarted(deploymentId: string, solutionName: string, waveNumber: number, totalWaves: number, tenantCount: number): Promise<void>;
70
+ /**
71
+ * Helper to send wave completed notification
72
+ */
73
+ notifyWaveCompleted(deploymentId: string, solutionName: string, waveNumber: number, successCount: number, failedCount: number): Promise<void>;
74
+ /**
75
+ * Helper to send tenant started notification
76
+ */
77
+ notifyTenantStarted(deploymentId: string, solutionName: string, tenantId: string, tenantName: string, waveNumber?: number): Promise<void>;
78
+ /**
79
+ * Helper to send tenant completed notification
80
+ */
81
+ notifyTenantCompleted(deploymentId: string, solutionName: string, tenantId: string, tenantName: string, waveNumber?: number): Promise<void>;
82
+ /**
83
+ * Helper to send tenant failed notification
84
+ */
85
+ notifyTenantFailed(deploymentId: string, solutionName: string, tenantId: string, tenantName: string, error: string, waveNumber?: number): Promise<void>;
86
+ /**
87
+ * Helper to send rollback started notification
88
+ */
89
+ notifyRollbackStarted(deploymentId: string, solutionName: string, tenantId: string, tenantName: string, previousVersion: string): Promise<void>;
90
+ /**
91
+ * Helper to send rollback completed notification
92
+ */
93
+ notifyRollbackCompleted(deploymentId: string, solutionName: string, tenantId: string, tenantName: string, success: boolean, restoredVersion?: string, error?: string): Promise<void>;
94
+ }
95
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/services/webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Copyright 2024 Pax8, 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 * as crypto from "node:crypto";
17
+ import { DEFAULT_WEBHOOK_RETRIES } from "../constants.js";
18
+ /**
19
+ * Service for sending webhook notifications
20
+ */
21
+ export class WebhookService {
22
+ webhooks;
23
+ constructor(webhooks = []) {
24
+ this.webhooks = webhooks;
25
+ }
26
+ /**
27
+ * Add a webhook configuration
28
+ */
29
+ addWebhook(webhook) {
30
+ this.webhooks.push(webhook);
31
+ }
32
+ /**
33
+ * Remove a webhook by URL
34
+ */
35
+ removeWebhook(url) {
36
+ this.webhooks = this.webhooks.filter((w) => w.url !== url);
37
+ }
38
+ /**
39
+ * Send a webhook notification for an event
40
+ */
41
+ async sendNotification(eventType, payload) {
42
+ const event = {
43
+ event: eventType,
44
+ timestamp: new Date().toISOString(),
45
+ ...payload,
46
+ };
47
+ // Find webhooks that are subscribed to this event
48
+ const subscribedWebhooks = this.webhooks.filter((w) => w.events.includes(eventType));
49
+ let sent = 0;
50
+ let failed = 0;
51
+ const errors = [];
52
+ await Promise.all(subscribedWebhooks.map(async (webhook) => {
53
+ const result = await this.sendToWebhook(webhook, event);
54
+ if (result.success) {
55
+ sent++;
56
+ }
57
+ else {
58
+ failed++;
59
+ errors.push({ url: webhook.url, error: result.error || "Unknown error" });
60
+ }
61
+ }));
62
+ return { sent, failed, errors };
63
+ }
64
+ /**
65
+ * Send event to a specific webhook with retry logic
66
+ */
67
+ async sendToWebhook(webhook, event) {
68
+ const maxRetries = webhook.retries ?? DEFAULT_WEBHOOK_RETRIES;
69
+ let lastError = "";
70
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
71
+ try {
72
+ const body = JSON.stringify(event);
73
+ const headers = {
74
+ "Content-Type": "application/json",
75
+ "User-Agent": "CopilotStudioDeployer/1.0",
76
+ "X-Webhook-Event": event.event,
77
+ "X-Deployment-Id": event.deploymentId,
78
+ ...webhook.headers,
79
+ };
80
+ // Add signature if secret is configured
81
+ if (webhook.secret) {
82
+ const signature = this.generateSignature(body, webhook.secret);
83
+ headers["X-Webhook-Signature"] = signature;
84
+ headers["X-Webhook-Signature-256"] = signature;
85
+ }
86
+ const response = await fetch(webhook.url, {
87
+ method: "POST",
88
+ headers,
89
+ body,
90
+ });
91
+ if (response.ok) {
92
+ return { success: true };
93
+ }
94
+ lastError = `HTTP ${response.status}: ${response.statusText}`;
95
+ }
96
+ catch (error) {
97
+ lastError = error instanceof Error ? error.message : String(error);
98
+ }
99
+ // Wait before retry with exponential backoff
100
+ if (attempt < maxRetries) {
101
+ await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt) * 1000));
102
+ }
103
+ }
104
+ return { success: false, error: lastError };
105
+ }
106
+ /**
107
+ * Generate HMAC-SHA256 signature for webhook payload
108
+ */
109
+ generateSignature(payload, secret) {
110
+ const hmac = crypto.createHmac("sha256", secret);
111
+ hmac.update(payload);
112
+ return `sha256=${hmac.digest("hex")}`;
113
+ }
114
+ /**
115
+ * Helper to send deployment started notification
116
+ */
117
+ async notifyDeploymentStarted(deploymentId, solutionName, totalTenants) {
118
+ await this.sendNotification("deployment.started", {
119
+ deploymentId,
120
+ solutionName,
121
+ status: "in_progress",
122
+ metadata: { totalTenants },
123
+ });
124
+ }
125
+ /**
126
+ * Helper to send deployment completed notification
127
+ */
128
+ async notifyDeploymentCompleted(deploymentId, solutionName, successCount, failedCount) {
129
+ const status = failedCount === 0
130
+ ? "completed"
131
+ : failedCount === successCount + failedCount
132
+ ? "failed"
133
+ : "completed";
134
+ await this.sendNotification("deployment.completed", {
135
+ deploymentId,
136
+ solutionName,
137
+ status,
138
+ metadata: { successCount, failedCount },
139
+ });
140
+ }
141
+ /**
142
+ * Helper to send deployment failed notification
143
+ */
144
+ async notifyDeploymentFailed(deploymentId, solutionName, error) {
145
+ await this.sendNotification("deployment.failed", {
146
+ deploymentId,
147
+ solutionName,
148
+ status: "failed",
149
+ error,
150
+ });
151
+ }
152
+ /**
153
+ * Helper to send wave started notification
154
+ */
155
+ async notifyWaveStarted(deploymentId, solutionName, waveNumber, totalWaves, tenantCount) {
156
+ await this.sendNotification("wave.started", {
157
+ deploymentId,
158
+ solutionName,
159
+ status: "in_progress",
160
+ waveNumber,
161
+ metadata: { totalWaves, tenantCount },
162
+ });
163
+ }
164
+ /**
165
+ * Helper to send wave completed notification
166
+ */
167
+ async notifyWaveCompleted(deploymentId, solutionName, waveNumber, successCount, failedCount) {
168
+ await this.sendNotification("wave.completed", {
169
+ deploymentId,
170
+ solutionName,
171
+ status: failedCount === 0 ? "completed" : "failed",
172
+ waveNumber,
173
+ metadata: { successCount, failedCount },
174
+ });
175
+ }
176
+ /**
177
+ * Helper to send tenant started notification
178
+ */
179
+ async notifyTenantStarted(deploymentId, solutionName, tenantId, tenantName, waveNumber) {
180
+ await this.sendNotification("tenant.started", {
181
+ deploymentId,
182
+ solutionName,
183
+ tenantId,
184
+ tenantName,
185
+ status: "in_progress",
186
+ waveNumber,
187
+ });
188
+ }
189
+ /**
190
+ * Helper to send tenant completed notification
191
+ */
192
+ async notifyTenantCompleted(deploymentId, solutionName, tenantId, tenantName, waveNumber) {
193
+ await this.sendNotification("tenant.completed", {
194
+ deploymentId,
195
+ solutionName,
196
+ tenantId,
197
+ tenantName,
198
+ status: "completed",
199
+ waveNumber,
200
+ });
201
+ }
202
+ /**
203
+ * Helper to send tenant failed notification
204
+ */
205
+ async notifyTenantFailed(deploymentId, solutionName, tenantId, tenantName, error, waveNumber) {
206
+ await this.sendNotification("tenant.failed", {
207
+ deploymentId,
208
+ solutionName,
209
+ tenantId,
210
+ tenantName,
211
+ status: "failed",
212
+ error,
213
+ waveNumber,
214
+ });
215
+ }
216
+ /**
217
+ * Helper to send rollback started notification
218
+ */
219
+ async notifyRollbackStarted(deploymentId, solutionName, tenantId, tenantName, previousVersion) {
220
+ await this.sendNotification("rollback.started", {
221
+ deploymentId,
222
+ solutionName,
223
+ tenantId,
224
+ tenantName,
225
+ status: "rolling_back",
226
+ metadata: { previousVersion },
227
+ });
228
+ }
229
+ /**
230
+ * Helper to send rollback completed notification
231
+ */
232
+ async notifyRollbackCompleted(deploymentId, solutionName, tenantId, tenantName, success, restoredVersion, error) {
233
+ await this.sendNotification("rollback.completed", {
234
+ deploymentId,
235
+ solutionName,
236
+ tenantId,
237
+ tenantName,
238
+ status: success ? "rolled_back" : "failed",
239
+ error,
240
+ metadata: restoredVersion ? { restoredVersion } : undefined,
241
+ });
242
+ }
243
+ }
244
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/services/webhook.ts"],"names":[],"mappings":"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"}