@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,403 @@
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
+ /**
17
+ * Solution Version Checker Service
18
+ * Detects version drift between expected and deployed solution versions across tenants
19
+ */
20
+ import { DataverseClient } from "../dataverse/client.js";
21
+ import { DEMO_TENANTS, DEMO_SOLUTIONS, } from "../mock/demo-data.js";
22
+ /**
23
+ * Compare two version strings (e.g., "1.0.0.5" vs "1.0.0.4")
24
+ * Returns: negative if a < b, 0 if equal, positive if a > b
25
+ */
26
+ export function compareVersions(a, b) {
27
+ const partsA = a.split(".").map((p) => parseInt(p, 10) || 0);
28
+ const partsB = b.split(".").map((p) => parseInt(p, 10) || 0);
29
+ const maxLen = Math.max(partsA.length, partsB.length);
30
+ for (let i = 0; i < maxLen; i++) {
31
+ const partA = partsA[i] || 0;
32
+ const partB = partsB[i] || 0;
33
+ if (partA < partB)
34
+ return -1;
35
+ if (partA > partB)
36
+ return 1;
37
+ }
38
+ return 0;
39
+ }
40
+ /**
41
+ * Get version status from comparison result
42
+ */
43
+ function getVersionStatus(expectedVersion, deployedVersion) {
44
+ if (!deployedVersion) {
45
+ return { status: "not_deployed", drift: 0 };
46
+ }
47
+ const comparison = compareVersions(deployedVersion, expectedVersion);
48
+ if (comparison === 0) {
49
+ return { status: "current", drift: 0 };
50
+ }
51
+ else if (comparison < 0) {
52
+ return { status: "outdated", drift: comparison };
53
+ }
54
+ else {
55
+ return { status: "ahead", drift: comparison };
56
+ }
57
+ }
58
+ /**
59
+ * Version Checker class for checking solution versions across tenants
60
+ */
61
+ export class VersionChecker {
62
+ cache = new Map();
63
+ CACHE_DURATION_MS = 30 * 60 * 1000; // 30 minutes
64
+ /**
65
+ * Check solution versions for a single tenant
66
+ */
67
+ async checkTenantVersions(tenant, expectedSolutions, tokenManager, skipCache = false) {
68
+ // Check cache first
69
+ if (!skipCache) {
70
+ const cached = this.cache.get(tenant.tenantId);
71
+ if (cached && Date.now() - cached.timestamp < this.CACHE_DURATION_MS) {
72
+ return cached.data;
73
+ }
74
+ }
75
+ // Demo mode - simulate version checking
76
+ if (process.env.DEMO_MODE === "true" || !tokenManager) {
77
+ return this.getDemoVersionStatus(tenant, expectedSolutions);
78
+ }
79
+ // Real mode - query Dataverse
80
+ try {
81
+ const client = new DataverseClient({
82
+ environmentUrl: tenant.environmentUrl,
83
+ tokenManager,
84
+ clientId: tokenManager.getClientId(),
85
+ });
86
+ const deployedSolutions = await client.querySolutions();
87
+ const solutionMap = new Map(deployedSolutions.map((s) => [s.uniquename.toLowerCase(), s]));
88
+ const solutions = expectedSolutions.map((expected) => {
89
+ const deployed = solutionMap.get(expected.uniqueName.toLowerCase());
90
+ const { status, drift } = getVersionStatus(expected.version, deployed?.version || null);
91
+ return {
92
+ uniqueName: expected.uniqueName,
93
+ friendlyName: expected.friendlyName,
94
+ expectedVersion: expected.version,
95
+ deployedVersion: deployed?.version || null,
96
+ isManaged: deployed?.ismanaged ?? true,
97
+ status,
98
+ versionDrift: drift,
99
+ };
100
+ });
101
+ const overallStatus = this.calculateOverallStatus(solutions);
102
+ const result = {
103
+ tenantId: tenant.tenantId,
104
+ tenantName: tenant.name,
105
+ environmentUrl: tenant.environmentUrl,
106
+ solutions,
107
+ overallStatus,
108
+ lastChecked: new Date().toISOString(),
109
+ };
110
+ // Cache the result
111
+ this.cache.set(tenant.tenantId, { data: result, timestamp: Date.now() });
112
+ return result;
113
+ }
114
+ catch (error) {
115
+ const errorMessage = error instanceof Error ? error.message : String(error);
116
+ return {
117
+ tenantId: tenant.tenantId,
118
+ tenantName: tenant.name,
119
+ environmentUrl: tenant.environmentUrl,
120
+ solutions: expectedSolutions.map((s) => ({
121
+ uniqueName: s.uniqueName,
122
+ friendlyName: s.friendlyName,
123
+ expectedVersion: s.version,
124
+ deployedVersion: null,
125
+ isManaged: true,
126
+ status: "unknown",
127
+ versionDrift: 0,
128
+ })),
129
+ overallStatus: "unknown",
130
+ lastChecked: new Date().toISOString(),
131
+ error: errorMessage,
132
+ };
133
+ }
134
+ }
135
+ /**
136
+ * Check versions for multiple tenants
137
+ */
138
+ async checkMultipleTenants(tenants, expectedSolutions, tokenManager, skipCache = false) {
139
+ // Run checks in parallel (with concurrency limit)
140
+ const CONCURRENCY = 5;
141
+ const results = [];
142
+ for (let i = 0; i < tenants.length; i += CONCURRENCY) {
143
+ const batch = tenants.slice(i, i + CONCURRENCY);
144
+ const batchResults = await Promise.all(batch.map((t) => this.checkTenantVersions(t, expectedSolutions, tokenManager, skipCache)));
145
+ results.push(...batchResults);
146
+ }
147
+ return results;
148
+ }
149
+ /**
150
+ * Get a summary of version drift across all tenants
151
+ */
152
+ async getVersionDriftSummary(tenants, expectedSolutions, tokenManager) {
153
+ const statuses = await this.checkMultipleTenants(tenants, expectedSolutions, tokenManager);
154
+ const solutionSummary = expectedSolutions.map((solution) => {
155
+ let atVersion = 0;
156
+ let behind = 0;
157
+ let notDeployed = 0;
158
+ for (const status of statuses) {
159
+ const solStatus = status.solutions.find((s) => s.uniqueName === solution.uniqueName);
160
+ if (!solStatus || solStatus.status === "unknown")
161
+ continue;
162
+ if (solStatus.status === "current" || solStatus.status === "ahead") {
163
+ atVersion++;
164
+ }
165
+ else if (solStatus.status === "outdated") {
166
+ behind++;
167
+ }
168
+ else if (solStatus.status === "not_deployed") {
169
+ notDeployed++;
170
+ }
171
+ }
172
+ return {
173
+ uniqueName: solution.uniqueName,
174
+ friendlyName: solution.friendlyName,
175
+ expectedVersion: solution.version,
176
+ tenantsAtVersion: atVersion,
177
+ tenantsBehind: behind,
178
+ tenantsNotDeployed: notDeployed,
179
+ };
180
+ });
181
+ return {
182
+ totalTenants: statuses.length,
183
+ currentTenants: statuses.filter((s) => s.overallStatus === "current").length,
184
+ outdatedTenants: statuses.filter((s) => s.overallStatus === "outdated" || s.overallStatus === "mixed").length,
185
+ unknownTenants: statuses.filter((s) => s.overallStatus === "unknown").length,
186
+ solutionSummary,
187
+ };
188
+ }
189
+ /**
190
+ * Clear cache for a tenant or all tenants
191
+ */
192
+ clearCache(tenantId) {
193
+ if (tenantId) {
194
+ this.cache.delete(tenantId);
195
+ }
196
+ else {
197
+ this.cache.clear();
198
+ }
199
+ }
200
+ // ============================================================================
201
+ // Private Methods
202
+ // ============================================================================
203
+ calculateOverallStatus(solutions) {
204
+ const statuses = solutions.map((s) => s.status);
205
+ if (statuses.every((s) => s === "unknown")) {
206
+ return "unknown";
207
+ }
208
+ const hasOutdated = statuses.some((s) => s === "outdated");
209
+ const hasCurrent = statuses.some((s) => s === "current" || s === "ahead");
210
+ if (hasOutdated && hasCurrent) {
211
+ return "mixed";
212
+ }
213
+ else if (hasOutdated) {
214
+ return "outdated";
215
+ }
216
+ else {
217
+ return "current";
218
+ }
219
+ }
220
+ getDemoVersionStatus(tenant, expectedSolutions) {
221
+ // Prefer the explicit `deployedSolutions` field on tenant metadata as the
222
+ // single source of truth. Both `solutions drift` and `solutions show
223
+ // --tenants` route through here so the two views never disagree.
224
+ const meta = tenant.metadata;
225
+ const deployedMap = new Map();
226
+ if (meta?.deployedSolutions) {
227
+ for (const ds of meta.deployedSolutions) {
228
+ deployedMap.set(ds.uniqueName.toLowerCase(), ds);
229
+ }
230
+ }
231
+ const solutions = expectedSolutions.map((expected, idx) => {
232
+ // Use the explicit per-tenant deployment when available.
233
+ if (deployedMap.size > 0) {
234
+ const ds = deployedMap.get(expected.uniqueName.toLowerCase());
235
+ const deployedVersion = ds?.deployedVersion ?? null;
236
+ const { status, drift } = this.diffPatchVersion(expected.version, deployedVersion);
237
+ return {
238
+ uniqueName: expected.uniqueName,
239
+ friendlyName: expected.friendlyName,
240
+ expectedVersion: expected.version,
241
+ deployedVersion,
242
+ isManaged: true,
243
+ status,
244
+ versionDrift: drift,
245
+ };
246
+ }
247
+ // Fallback path (kept for tenants that don't define `deployedSolutions`):
248
+ // deterministically generate a version drift scenario based on tenant ID.
249
+ const tenantIndex = parseInt(tenant.tenantId.substring(0, 8), 16);
250
+ const scenarioSeed = (tenantIndex + idx) % 10;
251
+ let deployedVersion = expected.version;
252
+ let status = "current";
253
+ let drift = 0;
254
+ if (scenarioSeed === 0) {
255
+ deployedVersion = null;
256
+ status = "not_deployed";
257
+ }
258
+ else if (scenarioSeed === 1 || scenarioSeed === 2) {
259
+ const parts = expected.version.split(".");
260
+ if (parts.length >= 3) {
261
+ parts[2] = String(Math.max(0, parseInt(parts[2], 10) - 1));
262
+ deployedVersion = parts.join(".");
263
+ status = "outdated";
264
+ drift = -1;
265
+ }
266
+ }
267
+ else if (scenarioSeed === 3) {
268
+ const parts = expected.version.split(".");
269
+ if (parts.length >= 3) {
270
+ parts[2] = String(Math.max(0, parseInt(parts[2], 10) - 2));
271
+ deployedVersion = parts.join(".");
272
+ status = "outdated";
273
+ drift = -2;
274
+ }
275
+ }
276
+ return {
277
+ uniqueName: expected.uniqueName,
278
+ friendlyName: expected.friendlyName,
279
+ expectedVersion: expected.version,
280
+ deployedVersion,
281
+ isManaged: true,
282
+ status,
283
+ versionDrift: drift,
284
+ };
285
+ });
286
+ const overallStatus = this.calculateOverallStatus(solutions);
287
+ return {
288
+ tenantId: tenant.tenantId,
289
+ tenantName: tenant.name,
290
+ environmentUrl: tenant.environmentUrl,
291
+ solutions,
292
+ overallStatus,
293
+ lastChecked: new Date().toISOString(),
294
+ };
295
+ }
296
+ /**
297
+ * Compute the version-drift status by comparing the rightmost-changed
298
+ * version segment. Used for demo-mode classification so `versionDrift`
299
+ * reflects how many releases behind the deployed version is — which is
300
+ * what the risk analyzer's `versions_behind` factor keys off of.
301
+ */
302
+ diffPatchVersion(expected, deployed) {
303
+ if (!deployed) {
304
+ return { status: "not_deployed", drift: 0 };
305
+ }
306
+ const expectedParts = expected.split(".").map((p) => parseInt(p, 10) || 0);
307
+ const deployedParts = deployed.split(".").map((p) => parseInt(p, 10) || 0);
308
+ const maxLen = Math.max(expectedParts.length, deployedParts.length);
309
+ let drift = 0;
310
+ let isBehind = false;
311
+ let isAhead = false;
312
+ for (let i = 0; i < maxLen; i++) {
313
+ const e = expectedParts[i] || 0;
314
+ const d = deployedParts[i] || 0;
315
+ if (d < e) {
316
+ // First differing segment determines the magnitude (e.g. 1.0.0.5 vs 1.0.0.1 -> drift 4).
317
+ if (!isBehind && !isAhead) {
318
+ drift = -(e - d);
319
+ isBehind = true;
320
+ }
321
+ }
322
+ else if (d > e) {
323
+ if (!isBehind && !isAhead) {
324
+ drift = d - e;
325
+ isAhead = true;
326
+ }
327
+ }
328
+ }
329
+ if (drift === 0)
330
+ return { status: "current", drift: 0 };
331
+ if (isBehind)
332
+ return { status: "outdated", drift };
333
+ return { status: "ahead", drift };
334
+ }
335
+ }
336
+ // Export singleton instance
337
+ export const versionChecker = new VersionChecker();
338
+ // ============================================================================
339
+ // Convenience functions for demo mode
340
+ // ============================================================================
341
+ /**
342
+ * Get demo version status for all tenants and solutions
343
+ */
344
+ export function getDemoVersionDriftSummary() {
345
+ const checker = new VersionChecker();
346
+ const expectedSolutions = DEMO_SOLUTIONS.map((s) => ({
347
+ uniqueName: s.uniqueName,
348
+ friendlyName: s.friendlyName,
349
+ version: s.version,
350
+ }));
351
+ // Synchronously generate demo data
352
+ const statuses = DEMO_TENANTS.filter((t) => t.enabled).map((tenant) => checker["getDemoVersionStatus"](tenant, expectedSolutions));
353
+ const solutionSummary = expectedSolutions.map((solution) => {
354
+ let atVersion = 0;
355
+ let behind = 0;
356
+ let notDeployed = 0;
357
+ for (const status of statuses) {
358
+ const solStatus = status.solutions.find((s) => s.uniqueName === solution.uniqueName);
359
+ if (!solStatus)
360
+ continue;
361
+ if (solStatus.status === "current" || solStatus.status === "ahead") {
362
+ atVersion++;
363
+ }
364
+ else if (solStatus.status === "outdated") {
365
+ behind++;
366
+ }
367
+ else if (solStatus.status === "not_deployed") {
368
+ notDeployed++;
369
+ }
370
+ }
371
+ return {
372
+ uniqueName: solution.uniqueName,
373
+ friendlyName: solution.friendlyName,
374
+ expectedVersion: solution.version,
375
+ tenantsAtVersion: atVersion,
376
+ tenantsBehind: behind,
377
+ tenantsNotDeployed: notDeployed,
378
+ };
379
+ });
380
+ return {
381
+ totalTenants: statuses.length,
382
+ currentTenants: statuses.filter((s) => s.overallStatus === "current").length,
383
+ outdatedTenants: statuses.filter((s) => s.overallStatus === "outdated" || s.overallStatus === "mixed").length,
384
+ unknownTenants: statuses.filter((s) => s.overallStatus === "unknown").length,
385
+ solutionSummary,
386
+ };
387
+ }
388
+ /**
389
+ * Get demo version status for a specific tenant
390
+ */
391
+ export function getDemoTenantVersionStatus(tenantId) {
392
+ const tenant = DEMO_TENANTS.find((t) => t.tenantId === tenantId);
393
+ if (!tenant)
394
+ return null;
395
+ const checker = new VersionChecker();
396
+ const expectedSolutions = DEMO_SOLUTIONS.map((s) => ({
397
+ uniqueName: s.uniqueName,
398
+ friendlyName: s.friendlyName,
399
+ version: s.version,
400
+ }));
401
+ return checker["getDemoVersionStatus"](tenant, expectedSolutions);
402
+ }
403
+ //# sourceMappingURL=version-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-checker.js","sourceRoot":"","sources":["../../src/services/version-checker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
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 { TenantConfig, Config } from "../config/schema.js";
17
+ /**
18
+ * Tenant with wave assignment
19
+ */
20
+ export interface TenantWithWave extends TenantConfig {
21
+ waveNumber: number;
22
+ waveName: string;
23
+ }
24
+ /**
25
+ * Wave execution plan
26
+ */
27
+ export interface WaveExecutionPlan {
28
+ waves: {
29
+ waveNumber: number;
30
+ name: string;
31
+ tenants: TenantConfig[];
32
+ maxParallel?: number;
33
+ waitAfterCompletion?: number;
34
+ continueOnFailure: boolean;
35
+ }[];
36
+ totalTenants: number;
37
+ }
38
+ /**
39
+ * Service for managing deployment waves
40
+ */
41
+ export declare class WaveService {
42
+ /**
43
+ * Create an execution plan from configuration
44
+ */
45
+ createExecutionPlan(config: Config, selectedTenants?: TenantConfig[]): WaveExecutionPlan;
46
+ /**
47
+ * Get tenants with wave assignments
48
+ */
49
+ getTenantsWithWaves(plan: WaveExecutionPlan): TenantWithWave[];
50
+ /**
51
+ * Calculate estimated deployment time based on waves
52
+ */
53
+ estimateDeploymentTime(plan: WaveExecutionPlan, avgTenantDeploymentMs?: number): {
54
+ totalEstimatedMs: number;
55
+ waveEstimates: {
56
+ waveNumber: number;
57
+ name: string;
58
+ estimatedMs: number;
59
+ }[];
60
+ };
61
+ /**
62
+ * Validate wave configuration
63
+ */
64
+ validateWaveConfig(config: Config): {
65
+ valid: boolean;
66
+ errors: string[];
67
+ warnings: string[];
68
+ };
69
+ /**
70
+ * Preview wave assignments without executing
71
+ */
72
+ previewWaves(config: Config): {
73
+ waves: {
74
+ waveNumber: number;
75
+ name: string;
76
+ tenantCount: number;
77
+ tenants: {
78
+ name: string;
79
+ tenantId: string;
80
+ tags: string[];
81
+ }[];
82
+ }[];
83
+ unassignedTenants: {
84
+ name: string;
85
+ tenantId: string;
86
+ tags: string[];
87
+ }[];
88
+ };
89
+ }
90
+ //# sourceMappingURL=waves.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waves.d.ts","sourceRoot":"","sources":["../../src/services/waves.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,EAAiB,MAAM,qBAAqB,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,YAAY,EAAE,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,iBAAiB,EAAE,OAAO,CAAC;KAC5B,EAAE,CAAC;IACJ,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB;;OAEG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,YAAY,EAAE,GAAG,iBAAiB;IA8ExF;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,cAAc,EAAE;IAgB9D;;OAEG;IACH,sBAAsB,CACpB,IAAI,EAAE,iBAAiB,EACvB,qBAAqB,GAAE,MAAc,GACpC;QACD,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE;YACb,UAAU,EAAE,MAAM,CAAC;YACnB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;SACrB,EAAE,CAAC;KACL;IAiCD;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE;IAyE5F;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG;QAC5B,KAAK,EAAE;YACL,UAAU,EAAE,MAAM,CAAC;YACnB,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,CAAC;YACpB,OAAO,EAAE;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,QAAQ,EAAE,MAAM,CAAC;gBAAC,IAAI,EAAE,MAAM,EAAE,CAAA;aAAE,EAAE,CAAC;SAC/D,EAAE,CAAC;QACJ,iBAAiB,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,EAAE,CAAA;SAAE,EAAE,CAAC;KACzE;CA2BF"}