@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.
- package/LICENSE +198 -0
- package/dist/auth/device-code-login.d.ts +40 -0
- package/dist/auth/device-code-login.d.ts.map +1 -0
- package/dist/auth/device-code-login.js +59 -0
- package/dist/auth/device-code-login.js.map +1 -0
- package/dist/auth/gdap-client.d.ts +81 -0
- package/dist/auth/gdap-client.d.ts.map +1 -0
- package/dist/auth/gdap-client.js +128 -0
- package/dist/auth/gdap-client.js.map +1 -0
- package/dist/auth/index.d.ts +19 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +19 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/token-manager.d.ts +54 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +150 -0
- package/dist/auth/token-manager.js.map +1 -0
- package/dist/client.d.ts +27 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +27 -0
- package/dist/client.js.map +1 -0
- package/dist/config/client.d.ts +24 -0
- package/dist/config/client.d.ts.map +1 -0
- package/dist/config/client.js +18 -0
- package/dist/config/client.js.map +1 -0
- package/dist/config/index.d.ts +18 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +18 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +81 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +271 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +751 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +556 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/constants.d.ts +116 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +170 -0
- package/dist/constants.js.map +1 -0
- package/dist/dataverse/agent-resolver.d.ts +98 -0
- package/dist/dataverse/agent-resolver.d.ts.map +1 -0
- package/dist/dataverse/agent-resolver.js +185 -0
- package/dist/dataverse/agent-resolver.js.map +1 -0
- package/dist/dataverse/client.d.ts +104 -0
- package/dist/dataverse/client.d.ts.map +1 -0
- package/dist/dataverse/client.js +272 -0
- package/dist/dataverse/client.js.map +1 -0
- package/dist/dataverse/connection-refs.d.ts +115 -0
- package/dist/dataverse/connection-refs.d.ts.map +1 -0
- package/dist/dataverse/connection-refs.js +203 -0
- package/dist/dataverse/connection-refs.js.map +1 -0
- package/dist/dataverse/index.d.ts +20 -0
- package/dist/dataverse/index.d.ts.map +1 -0
- package/dist/dataverse/index.js +20 -0
- package/dist/dataverse/index.js.map +1 -0
- package/dist/dataverse/solution-ops.d.ts +100 -0
- package/dist/dataverse/solution-ops.d.ts.map +1 -0
- package/dist/dataverse/solution-ops.js +288 -0
- package/dist/dataverse/solution-ops.js.map +1 -0
- package/dist/errors.d.ts +171 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +178 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/mock/demo-data.d.ts +213 -0
- package/dist/mock/demo-data.d.ts.map +1 -0
- package/dist/mock/demo-data.js +1096 -0
- package/dist/mock/demo-data.js.map +1 -0
- package/dist/mock/demo-deployment-store.d.ts +77 -0
- package/dist/mock/demo-deployment-store.d.ts.map +1 -0
- package/dist/mock/demo-deployment-store.js +85 -0
- package/dist/mock/demo-deployment-store.js.map +1 -0
- package/dist/powerplatform/admin-client.d.ts +226 -0
- package/dist/powerplatform/admin-client.d.ts.map +1 -0
- package/dist/powerplatform/admin-client.js +315 -0
- package/dist/powerplatform/admin-client.js.map +1 -0
- package/dist/powerplatform/index.d.ts +18 -0
- package/dist/powerplatform/index.d.ts.map +1 -0
- package/dist/powerplatform/index.js +18 -0
- package/dist/powerplatform/index.js.map +1 -0
- package/dist/powerplatform/tenant-discovery.d.ts +100 -0
- package/dist/powerplatform/tenant-discovery.d.ts.map +1 -0
- package/dist/powerplatform/tenant-discovery.js +205 -0
- package/dist/powerplatform/tenant-discovery.js.map +1 -0
- package/dist/preconditions/check.d.ts +41 -0
- package/dist/preconditions/check.d.ts.map +1 -0
- package/dist/preconditions/check.js +173 -0
- package/dist/preconditions/check.js.map +1 -0
- package/dist/preconditions/index.d.ts +20 -0
- package/dist/preconditions/index.d.ts.map +1 -0
- package/dist/preconditions/index.js +20 -0
- package/dist/preconditions/index.js.map +1 -0
- package/dist/preconditions/loader.d.ts +33 -0
- package/dist/preconditions/loader.d.ts.map +1 -0
- package/dist/preconditions/loader.js +65 -0
- package/dist/preconditions/loader.js.map +1 -0
- package/dist/preconditions/schema.d.ts +103 -0
- package/dist/preconditions/schema.d.ts.map +1 -0
- package/dist/preconditions/schema.js +93 -0
- package/dist/preconditions/schema.js.map +1 -0
- package/dist/preconditions/types.d.ts +118 -0
- package/dist/preconditions/types.d.ts.map +1 -0
- package/dist/preconditions/types.js +17 -0
- package/dist/preconditions/types.js.map +1 -0
- package/dist/queue/index.d.ts +17 -0
- package/dist/queue/index.d.ts.map +1 -0
- package/dist/queue/index.js +17 -0
- package/dist/queue/index.js.map +1 -0
- package/dist/queue/memory-queue.d.ts +86 -0
- package/dist/queue/memory-queue.d.ts.map +1 -0
- package/dist/queue/memory-queue.js +221 -0
- package/dist/queue/memory-queue.js.map +1 -0
- package/dist/services/audit-log.d.ts +59 -0
- package/dist/services/audit-log.d.ts.map +1 -0
- package/dist/services/audit-log.js +193 -0
- package/dist/services/audit-log.js.map +1 -0
- package/dist/services/auth-error-parser.d.ts +36 -0
- package/dist/services/auth-error-parser.d.ts.map +1 -0
- package/dist/services/auth-error-parser.js +90 -0
- package/dist/services/auth-error-parser.js.map +1 -0
- package/dist/services/deployment-doctor.d.ts +109 -0
- package/dist/services/deployment-doctor.d.ts.map +1 -0
- package/dist/services/deployment-doctor.js +476 -0
- package/dist/services/deployment-doctor.js.map +1 -0
- package/dist/services/deployment-notifications.d.ts +41 -0
- package/dist/services/deployment-notifications.d.ts.map +1 -0
- package/dist/services/deployment-notifications.js +161 -0
- package/dist/services/deployment-notifications.js.map +1 -0
- package/dist/services/deployment-progress.d.ts +89 -0
- package/dist/services/deployment-progress.d.ts.map +1 -0
- package/dist/services/deployment-progress.js +244 -0
- package/dist/services/deployment-progress.js.map +1 -0
- package/dist/services/deployment-service.d.ts +97 -0
- package/dist/services/deployment-service.d.ts.map +1 -0
- package/dist/services/deployment-service.js +375 -0
- package/dist/services/deployment-service.js.map +1 -0
- package/dist/services/drift-analyzer.d.ts +86 -0
- package/dist/services/drift-analyzer.d.ts.map +1 -0
- package/dist/services/drift-analyzer.js +273 -0
- package/dist/services/drift-analyzer.js.map +1 -0
- package/dist/services/environment-setup.d.ts +97 -0
- package/dist/services/environment-setup.d.ts.map +1 -0
- package/dist/services/environment-setup.js +250 -0
- package/dist/services/environment-setup.js.map +1 -0
- package/dist/services/health-check.d.ts +168 -0
- package/dist/services/health-check.d.ts.map +1 -0
- package/dist/services/health-check.js +705 -0
- package/dist/services/health-check.js.map +1 -0
- package/dist/services/index.d.ts +39 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +39 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/logger.d.ts +139 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/logger.js +268 -0
- package/dist/services/logger.js.map +1 -0
- package/dist/services/notification-service.d.ts +55 -0
- package/dist/services/notification-service.d.ts.map +1 -0
- package/dist/services/notification-service.js +184 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/risk-analyzer.d.ts +252 -0
- package/dist/services/risk-analyzer.d.ts.map +1 -0
- package/dist/services/risk-analyzer.js +866 -0
- package/dist/services/risk-analyzer.js.map +1 -0
- package/dist/services/rollback.d.ts +57 -0
- package/dist/services/rollback.d.ts.map +1 -0
- package/dist/services/rollback.js +270 -0
- package/dist/services/rollback.js.map +1 -0
- package/dist/services/scheduler.d.ts +80 -0
- package/dist/services/scheduler.d.ts.map +1 -0
- package/dist/services/scheduler.js +350 -0
- package/dist/services/scheduler.js.map +1 -0
- package/dist/services/secrets.d.ts +31 -0
- package/dist/services/secrets.d.ts.map +1 -0
- package/dist/services/secrets.js +206 -0
- package/dist/services/secrets.js.map +1 -0
- package/dist/services/settings-service.d.ts +132 -0
- package/dist/services/settings-service.d.ts.map +1 -0
- package/dist/services/settings-service.js +378 -0
- package/dist/services/settings-service.js.map +1 -0
- package/dist/services/solution-diff.d.ts +127 -0
- package/dist/services/solution-diff.d.ts.map +1 -0
- package/dist/services/solution-diff.js +260 -0
- package/dist/services/solution-diff.js.map +1 -0
- package/dist/services/solution-mode-detector.d.ts +35 -0
- package/dist/services/solution-mode-detector.d.ts.map +1 -0
- package/dist/services/solution-mode-detector.js +84 -0
- package/dist/services/solution-mode-detector.js.map +1 -0
- package/dist/services/tenant-resolver.d.ts +55 -0
- package/dist/services/tenant-resolver.d.ts.map +1 -0
- package/dist/services/tenant-resolver.js +126 -0
- package/dist/services/tenant-resolver.js.map +1 -0
- package/dist/services/unmanaged-customizations.d.ts +104 -0
- package/dist/services/unmanaged-customizations.d.ts.map +1 -0
- package/dist/services/unmanaged-customizations.js +521 -0
- package/dist/services/unmanaged-customizations.js.map +1 -0
- package/dist/services/url-templater.d.ts +184 -0
- package/dist/services/url-templater.d.ts.map +1 -0
- package/dist/services/url-templater.js +327 -0
- package/dist/services/url-templater.js.map +1 -0
- package/dist/services/version-checker.d.ts +108 -0
- package/dist/services/version-checker.d.ts.map +1 -0
- package/dist/services/version-checker.js +403 -0
- package/dist/services/version-checker.js.map +1 -0
- package/dist/services/waves.d.ts +90 -0
- package/dist/services/waves.d.ts.map +1 -0
- package/dist/services/waves.js +222 -0
- package/dist/services/waves.js.map +1 -0
- package/dist/services/webhook.d.ts +95 -0
- package/dist/services/webhook.d.ts.map +1 -0
- package/dist/services/webhook.js +244 -0
- package/dist/services/webhook.js.map +1 -0
- package/dist/utils/deployment-tools.d.ts +110 -0
- package/dist/utils/deployment-tools.d.ts.map +1 -0
- package/dist/utils/deployment-tools.js +121 -0
- package/dist/utils/deployment-tools.js.map +1 -0
- package/dist/utils/index.d.ts +17 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +1 -0
- 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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"}
|