@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,350 @@
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 { MAX_SCHEDULE_ITERATIONS } from "../constants.js";
17
+ /**
18
+ * Service for scheduled deployment operations
19
+ */
20
+ export class SchedulerService {
21
+ /**
22
+ * Check if a deployment is allowed within the maintenance window
23
+ */
24
+ isWithinMaintenanceWindow(schedule, date = new Date()) {
25
+ if (!schedule.maintenanceWindow) {
26
+ return true; // No maintenance window = always allowed
27
+ }
28
+ const { start, end, daysOfWeek } = schedule.maintenanceWindow;
29
+ // Convert to target timezone
30
+ const targetDate = this.convertToTimezone(date, schedule.timezone || "UTC");
31
+ // Check day of week
32
+ if (daysOfWeek && daysOfWeek.length > 0) {
33
+ const dayOfWeek = targetDate.getDay();
34
+ if (!daysOfWeek.includes(dayOfWeek)) {
35
+ return false;
36
+ }
37
+ }
38
+ // Parse start and end times
39
+ const [startHour, startMinute] = start.split(":").map(Number);
40
+ const [endHour, endMinute] = end.split(":").map(Number);
41
+ const currentHour = targetDate.getHours();
42
+ const currentMinute = targetDate.getMinutes();
43
+ const currentTimeMinutes = currentHour * 60 + currentMinute;
44
+ const startTimeMinutes = startHour * 60 + startMinute;
45
+ const endTimeMinutes = endHour * 60 + endMinute;
46
+ // Handle windows that span midnight
47
+ if (startTimeMinutes > endTimeMinutes) {
48
+ // Window spans midnight (e.g., 22:00 - 06:00)
49
+ return currentTimeMinutes >= startTimeMinutes || currentTimeMinutes < endTimeMinutes;
50
+ }
51
+ // Normal window (e.g., 02:00 - 06:00)
52
+ return currentTimeMinutes >= startTimeMinutes && currentTimeMinutes < endTimeMinutes;
53
+ }
54
+ /**
55
+ * Get the next maintenance window start time
56
+ */
57
+ getNextMaintenanceWindow(schedule, from = new Date()) {
58
+ if (!schedule.maintenanceWindow) {
59
+ return null;
60
+ }
61
+ const { start, daysOfWeek } = schedule.maintenanceWindow;
62
+ const [startHour, startMinute] = start.split(":").map(Number);
63
+ // Convert to target timezone
64
+ const targetDate = this.convertToTimezone(from, schedule.timezone || "UTC");
65
+ // Start from the current day
66
+ const candidate = new Date(targetDate);
67
+ candidate.setHours(startHour, startMinute, 0, 0);
68
+ // If we're past today's window start, move to tomorrow
69
+ if (candidate <= targetDate) {
70
+ candidate.setDate(candidate.getDate() + 1);
71
+ }
72
+ // Find the next valid day
73
+ for (let i = 0; i < 7; i++) {
74
+ const dayOfWeek = candidate.getDay();
75
+ if (!daysOfWeek || daysOfWeek.length === 0 || daysOfWeek.includes(dayOfWeek)) {
76
+ // Convert back to local time
77
+ return this.convertFromTimezone(candidate, schedule.timezone || "UTC");
78
+ }
79
+ candidate.setDate(candidate.getDate() + 1);
80
+ }
81
+ return null;
82
+ }
83
+ /**
84
+ * Parse a cron expression
85
+ */
86
+ parseCron(cron) {
87
+ const parts = cron.trim().split(/\s+/);
88
+ if (parts.length !== 5) {
89
+ return null;
90
+ }
91
+ try {
92
+ return {
93
+ minutes: this.parseCronPart(parts[0], 0, 59),
94
+ hours: this.parseCronPart(parts[1], 0, 23),
95
+ daysOfMonth: this.parseCronPart(parts[2], 1, 31),
96
+ months: this.parseCronPart(parts[3], 1, 12),
97
+ daysOfWeek: this.parseCronPart(parts[4], 0, 6),
98
+ };
99
+ }
100
+ catch {
101
+ return null;
102
+ }
103
+ }
104
+ /**
105
+ * Get the next scheduled run time based on cron expression
106
+ */
107
+ getNextCronRun(schedule, from = new Date()) {
108
+ if (!schedule.cron) {
109
+ return null;
110
+ }
111
+ const parsed = this.parseCron(schedule.cron);
112
+ if (!parsed) {
113
+ throw new Error(`Invalid cron expression: ${schedule.cron}`);
114
+ }
115
+ // Convert to target timezone
116
+ const targetDate = this.convertToTimezone(from, schedule.timezone || "UTC");
117
+ // Start from the next minute
118
+ const candidate = new Date(targetDate);
119
+ candidate.setSeconds(0, 0);
120
+ candidate.setMinutes(candidate.getMinutes() + 1);
121
+ // Search for up to 1 year
122
+ const maxIterations = MAX_SCHEDULE_ITERATIONS;
123
+ for (let i = 0; i < maxIterations; i++) {
124
+ if (this.matchesCron(candidate, parsed)) {
125
+ // Also check maintenance window if configured
126
+ if (!schedule.maintenanceWindow || this.isWithinMaintenanceWindow(schedule, candidate)) {
127
+ return this.convertFromTimezone(candidate, schedule.timezone || "UTC");
128
+ }
129
+ }
130
+ candidate.setMinutes(candidate.getMinutes() + 1);
131
+ }
132
+ return null;
133
+ }
134
+ /**
135
+ * Check if a date matches a cron expression
136
+ */
137
+ matchesCron(date, cron) {
138
+ return (cron.minutes.includes(date.getMinutes()) &&
139
+ cron.hours.includes(date.getHours()) &&
140
+ cron.daysOfMonth.includes(date.getDate()) &&
141
+ cron.months.includes(date.getMonth() + 1) &&
142
+ cron.daysOfWeek.includes(date.getDay()));
143
+ }
144
+ /**
145
+ * Validate a cron expression
146
+ */
147
+ validateCron(cron) {
148
+ const parts = cron.trim().split(/\s+/);
149
+ if (parts.length !== 5) {
150
+ return {
151
+ valid: false,
152
+ error: `Expected 5 parts, got ${parts.length}`,
153
+ };
154
+ }
155
+ const names = ["minute", "hour", "day of month", "month", "day of week"];
156
+ const ranges = [
157
+ [0, 59],
158
+ [0, 23],
159
+ [1, 31],
160
+ [1, 12],
161
+ [0, 6],
162
+ ];
163
+ for (let i = 0; i < 5; i++) {
164
+ try {
165
+ this.parseCronPart(parts[i], ranges[i][0], ranges[i][1]);
166
+ }
167
+ catch (error) {
168
+ return {
169
+ valid: false,
170
+ error: `Invalid ${names[i]}: ${error instanceof Error ? error.message : String(error)}`,
171
+ };
172
+ }
173
+ }
174
+ return { valid: true };
175
+ }
176
+ /**
177
+ * Parse a single part of a cron expression
178
+ */
179
+ parseCronPart(part, min, max) {
180
+ const values = [];
181
+ // Handle wildcards
182
+ if (part === "*") {
183
+ for (let i = min; i <= max; i++) {
184
+ values.push(i);
185
+ }
186
+ return values;
187
+ }
188
+ // Handle comma-separated values
189
+ const segments = part.split(",");
190
+ for (const segment of segments) {
191
+ // Handle step values (e.g., */5 or 0-30/5)
192
+ if (segment.includes("/")) {
193
+ const [range, stepStr] = segment.split("/");
194
+ const step = parseInt(stepStr, 10);
195
+ if (isNaN(step) || step < 1) {
196
+ throw new Error(`Invalid step value: ${stepStr}`);
197
+ }
198
+ let rangeMin = min;
199
+ let rangeMax = max;
200
+ if (range !== "*") {
201
+ if (range.includes("-")) {
202
+ const [rMin, rMax] = range.split("-").map(Number);
203
+ rangeMin = rMin;
204
+ rangeMax = rMax;
205
+ }
206
+ else {
207
+ rangeMin = parseInt(range, 10);
208
+ rangeMax = max;
209
+ }
210
+ }
211
+ for (let i = rangeMin; i <= rangeMax; i += step) {
212
+ if (i >= min && i <= max && !values.includes(i)) {
213
+ values.push(i);
214
+ }
215
+ }
216
+ }
217
+ // Handle ranges (e.g., 0-5)
218
+ else if (segment.includes("-")) {
219
+ const [rangeMin, rangeMax] = segment.split("-").map(Number);
220
+ if (isNaN(rangeMin) || isNaN(rangeMax)) {
221
+ throw new Error(`Invalid range: ${segment}`);
222
+ }
223
+ for (let i = rangeMin; i <= rangeMax; i++) {
224
+ if (i >= min && i <= max && !values.includes(i)) {
225
+ values.push(i);
226
+ }
227
+ }
228
+ }
229
+ // Handle single values
230
+ else {
231
+ const value = parseInt(segment, 10);
232
+ if (isNaN(value)) {
233
+ throw new Error(`Invalid value: ${segment}`);
234
+ }
235
+ if (value >= min && value <= max && !values.includes(value)) {
236
+ values.push(value);
237
+ }
238
+ }
239
+ }
240
+ if (values.length === 0) {
241
+ throw new Error(`No valid values in range ${min}-${max}`);
242
+ }
243
+ return values.sort((a, b) => a - b);
244
+ }
245
+ /**
246
+ * Convert a date to a specific timezone
247
+ */
248
+ convertToTimezone(date, timezone) {
249
+ const formatter = new Intl.DateTimeFormat("en-US", {
250
+ timeZone: timezone,
251
+ year: "numeric",
252
+ month: "2-digit",
253
+ day: "2-digit",
254
+ hour: "2-digit",
255
+ minute: "2-digit",
256
+ second: "2-digit",
257
+ hour12: false,
258
+ });
259
+ const parts = formatter.formatToParts(date);
260
+ const values = {};
261
+ for (const part of parts) {
262
+ if (part.type !== "literal") {
263
+ values[part.type] = parseInt(part.value, 10);
264
+ }
265
+ }
266
+ return new Date(values.year, values.month - 1, values.day, values.hour, values.minute, values.second);
267
+ }
268
+ /**
269
+ * Convert a date from a specific timezone to local
270
+ */
271
+ convertFromTimezone(date, timezone) {
272
+ // Get the offset for the target timezone
273
+ const targetStr = date.toLocaleString("en-US", { timeZone: timezone });
274
+ const localStr = date.toLocaleString("en-US");
275
+ const targetDate = new Date(targetStr);
276
+ const localDate = new Date(localStr);
277
+ const offset = localDate.getTime() - targetDate.getTime();
278
+ return new Date(date.getTime() + offset);
279
+ }
280
+ /**
281
+ * Create a human-readable description of a cron expression
282
+ */
283
+ describeCron(cron) {
284
+ const parsed = this.parseCron(cron);
285
+ if (!parsed) {
286
+ return "Invalid cron expression";
287
+ }
288
+ const parts = [];
289
+ // Minutes
290
+ if (parsed.minutes.length === 60) {
291
+ parts.push("every minute");
292
+ }
293
+ else if (parsed.minutes.length === 1) {
294
+ parts.push(`at minute ${parsed.minutes[0]}`);
295
+ }
296
+ else {
297
+ parts.push(`at minutes ${parsed.minutes.join(", ")}`);
298
+ }
299
+ // Hours
300
+ if (parsed.hours.length === 24) {
301
+ parts.push("of every hour");
302
+ }
303
+ else if (parsed.hours.length === 1) {
304
+ parts.push(`of ${parsed.hours[0]}:00`);
305
+ }
306
+ else {
307
+ parts.push(`of hours ${parsed.hours.join(", ")}`);
308
+ }
309
+ // Days of week
310
+ const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
311
+ if (parsed.daysOfWeek.length < 7) {
312
+ parts.push(`on ${parsed.daysOfWeek.map((d) => dayNames[d]).join(", ")}`);
313
+ }
314
+ // Months
315
+ const monthNames = [
316
+ "Jan",
317
+ "Feb",
318
+ "Mar",
319
+ "Apr",
320
+ "May",
321
+ "Jun",
322
+ "Jul",
323
+ "Aug",
324
+ "Sep",
325
+ "Oct",
326
+ "Nov",
327
+ "Dec",
328
+ ];
329
+ if (parsed.months.length < 12) {
330
+ parts.push(`in ${parsed.months.map((m) => monthNames[m - 1]).join(", ")}`);
331
+ }
332
+ return parts.join(" ");
333
+ }
334
+ /**
335
+ * Generate next N scheduled run times
336
+ */
337
+ getNextRuns(schedule, count = 5) {
338
+ const runs = [];
339
+ let from = new Date();
340
+ for (let i = 0; i < count; i++) {
341
+ const next = this.getNextCronRun(schedule, from);
342
+ if (!next)
343
+ break;
344
+ runs.push(next);
345
+ from = new Date(next.getTime() + 60000); // Add 1 minute
346
+ }
347
+ return runs;
348
+ }
349
+ }
350
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/services/scheduler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
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
+ export interface SecretProvider {
17
+ getSecret(name: string): Promise<string | undefined>;
18
+ setSecret?(name: string, value: string): Promise<void>;
19
+ deleteSecret?(name: string): Promise<void>;
20
+ }
21
+ export declare class SecretsManager {
22
+ private provider;
23
+ constructor(provider?: SecretProvider);
24
+ getSecret(name: string): Promise<string | undefined>;
25
+ getRequiredSecret(name: string): Promise<string>;
26
+ getDeploymentSecrets(): Promise<{
27
+ partnerClientSecret: string;
28
+ }>;
29
+ }
30
+ export declare function getSecretsManager(): SecretsManager;
31
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/services/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrD,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AA6KD,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAiB;gBAErB,QAAQ,CAAC,EAAE,cAAc;IAoB/B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAIpD,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAShD,oBAAoB,IAAI,OAAO,CAAC;QACpC,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;CAOH;AAKD,wBAAgB,iBAAiB,IAAI,cAAc,CAKlD"}
@@ -0,0 +1,206 @@
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 { coreLogger } from "./logger.js";
17
+ import { DEFAULT_SECRETS_CACHE_TTL_MS } from "../constants.js";
18
+ const logger = coreLogger.child({ service: "secrets" });
19
+ // Environment variable provider (for development/simple deployments)
20
+ class EnvSecretProvider {
21
+ prefix;
22
+ constructor(prefix = "") {
23
+ this.prefix = prefix;
24
+ }
25
+ async getSecret(name) {
26
+ const envName = this.prefix + name.toUpperCase().replace(/-/g, "_");
27
+ return process.env[envName];
28
+ }
29
+ }
30
+ // Azure Key Vault provider
31
+ class AzureKeyVaultProvider {
32
+ vaultUrl;
33
+ accessToken;
34
+ tokenExpiry;
35
+ cache = new Map();
36
+ cacheTtlMs;
37
+ constructor(options) {
38
+ this.vaultUrl = options.vaultUrl;
39
+ this.cacheTtlMs = options.cacheTtlMs ?? DEFAULT_SECRETS_CACHE_TTL_MS;
40
+ }
41
+ async getAccessToken() {
42
+ // Check if we have a valid cached token
43
+ if (this.accessToken && this.tokenExpiry && this.tokenExpiry > new Date()) {
44
+ return this.accessToken;
45
+ }
46
+ // Use managed identity or Azure CLI credentials
47
+ // In production, this would use @azure/identity DefaultAzureCredential
48
+ const tokenUrl = "http://169.254.169.254/metadata/identity/oauth2/token?" +
49
+ "api-version=2019-08-01&resource=https://vault.azure.net";
50
+ try {
51
+ const response = await fetch(tokenUrl, {
52
+ headers: { Metadata: "true" },
53
+ });
54
+ if (!response.ok) {
55
+ throw new Error(`Token request failed: ${response.status}`);
56
+ }
57
+ const data = (await response.json());
58
+ this.accessToken = data.access_token;
59
+ this.tokenExpiry = new Date(Date.now() + (data.expires_in - 60) * 1000);
60
+ return this.accessToken;
61
+ }
62
+ catch (error) {
63
+ logger.error("Failed to get Azure token", error);
64
+ throw new Error("Failed to authenticate with Azure Key Vault");
65
+ }
66
+ }
67
+ async getSecret(name) {
68
+ // Check cache first
69
+ const cached = this.cache.get(name);
70
+ if (cached && cached.expiry > new Date()) {
71
+ return cached.value;
72
+ }
73
+ try {
74
+ const token = await this.getAccessToken();
75
+ const url = `${this.vaultUrl}/secrets/${name}?api-version=7.4`;
76
+ const response = await fetch(url, {
77
+ headers: {
78
+ Authorization: `Bearer ${token}`,
79
+ },
80
+ });
81
+ if (response.status === 404) {
82
+ return undefined;
83
+ }
84
+ if (!response.ok) {
85
+ throw new Error(`Key Vault request failed: ${response.status}`);
86
+ }
87
+ const data = (await response.json());
88
+ const value = data.value;
89
+ // Cache the secret
90
+ this.cache.set(name, {
91
+ value,
92
+ expiry: new Date(Date.now() + this.cacheTtlMs),
93
+ });
94
+ return value;
95
+ }
96
+ catch (error) {
97
+ logger.error(`Failed to get secret: ${name}`, error);
98
+ throw error;
99
+ }
100
+ }
101
+ async setSecret(name, value) {
102
+ const token = await this.getAccessToken();
103
+ const url = `${this.vaultUrl}/secrets/${name}?api-version=7.4`;
104
+ const response = await fetch(url, {
105
+ method: "PUT",
106
+ headers: {
107
+ Authorization: `Bearer ${token}`,
108
+ "Content-Type": "application/json",
109
+ },
110
+ body: JSON.stringify({ value }),
111
+ });
112
+ if (!response.ok) {
113
+ throw new Error(`Failed to set secret: ${response.status}`);
114
+ }
115
+ // Update cache
116
+ this.cache.set(name, {
117
+ value,
118
+ expiry: new Date(Date.now() + this.cacheTtlMs),
119
+ });
120
+ }
121
+ async deleteSecret(name) {
122
+ const token = await this.getAccessToken();
123
+ const url = `${this.vaultUrl}/secrets/${name}?api-version=7.4`;
124
+ const response = await fetch(url, {
125
+ method: "DELETE",
126
+ headers: {
127
+ Authorization: `Bearer ${token}`,
128
+ },
129
+ });
130
+ if (!response.ok && response.status !== 404) {
131
+ throw new Error(`Failed to delete secret: ${response.status}`);
132
+ }
133
+ this.cache.delete(name);
134
+ }
135
+ clearCache() {
136
+ this.cache.clear();
137
+ }
138
+ }
139
+ // Composite provider that tries multiple sources
140
+ class CompositeSecretProvider {
141
+ providers;
142
+ constructor(providers) {
143
+ this.providers = providers;
144
+ }
145
+ async getSecret(name) {
146
+ for (const provider of this.providers) {
147
+ try {
148
+ const value = await provider.getSecret(name);
149
+ if (value !== undefined) {
150
+ return value;
151
+ }
152
+ }
153
+ catch (error) {
154
+ logger.warn(`Provider failed for secret ${name}`, { error });
155
+ // Continue to next provider
156
+ }
157
+ }
158
+ return undefined;
159
+ }
160
+ }
161
+ export class SecretsManager {
162
+ provider;
163
+ constructor(provider) {
164
+ if (provider) {
165
+ this.provider = provider;
166
+ }
167
+ else {
168
+ // Auto-configure based on environment
169
+ const providers = [];
170
+ // Azure Key Vault if configured
171
+ const vaultUrl = process.env.AZURE_KEY_VAULT_URL;
172
+ if (vaultUrl) {
173
+ providers.push(new AzureKeyVaultProvider({ vaultUrl }));
174
+ }
175
+ // Always include env vars as fallback
176
+ providers.push(new EnvSecretProvider());
177
+ this.provider = new CompositeSecretProvider(providers);
178
+ }
179
+ }
180
+ async getSecret(name) {
181
+ return this.provider.getSecret(name);
182
+ }
183
+ async getRequiredSecret(name) {
184
+ const value = await this.getSecret(name);
185
+ if (value === undefined) {
186
+ throw new Error(`Required secret not found: ${name}`);
187
+ }
188
+ return value;
189
+ }
190
+ // Get all secrets needed for deployment
191
+ async getDeploymentSecrets() {
192
+ const partnerClientSecret = await this.getRequiredSecret("PARTNER_CLIENT_SECRET");
193
+ return {
194
+ partnerClientSecret,
195
+ };
196
+ }
197
+ }
198
+ // Singleton instance
199
+ let secretsManagerInstance = null;
200
+ export function getSecretsManager() {
201
+ if (!secretsManagerInstance) {
202
+ secretsManagerInstance = new SecretsManager();
203
+ }
204
+ return secretsManagerInstance;
205
+ }
206
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/services/secrets.ts"],"names":[],"mappings":"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"}