@ebowwa/hetzner 0.1.0 → 0.2.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/actions.js +721 -439
- package/auth.js +15 -11
- package/bootstrap/cloud-init.js +109 -65
- package/bootstrap/firewall.js +30 -17
- package/bootstrap/genesis.js +89 -71
- package/bootstrap/index.js +31 -7
- package/bootstrap/kernel-hardening.js +10 -6
- package/bootstrap/kernel-hardening.test.js +182 -0
- package/bootstrap/security-audit.js +10 -6
- package/bootstrap/ssh-hardening.js +10 -6
- package/client.js +180 -83
- package/config.js +4 -2
- package/errors.js +183 -108
- package/index.js +57 -12
- package/index.ts +4 -0
- package/onboarding/doppler.ts +116 -0
- package/onboarding/git.ts +133 -0
- package/onboarding/index.ts +18 -0
- package/onboarding/onboarding.ts +193 -0
- package/onboarding/tailscale.ts +159 -0
- package/onboarding/types.ts +115 -0
- package/package.json +6 -1
- package/pricing.js +216 -113
- package/schemas.js +322 -315
- package/server-status.js +122 -0
- package/servers.js +530 -287
- package/ssh-keys.js +153 -63
- package/ssh-setup.js +253 -0
- package/ssh-setup.ts +1 -1
- package/types.js +11 -8
- package/volumes.js +205 -82
package/pricing.js
CHANGED
|
@@ -1,53 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Hetzner pricing operations - fetch server types, locations, and calculate costs
|
|
3
4
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
6
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
7
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
8
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
9
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
10
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
11
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
15
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
16
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
17
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
18
|
+
function step(op) {
|
|
19
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
20
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
21
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
22
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
23
|
+
switch (op[0]) {
|
|
24
|
+
case 0: case 1: t = op; break;
|
|
25
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
26
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
27
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
28
|
+
default:
|
|
29
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
30
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
31
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
32
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
33
|
+
if (t[2]) _.ops.pop();
|
|
34
|
+
_.trys.pop(); continue;
|
|
35
|
+
}
|
|
36
|
+
op = body.call(thisArg, _);
|
|
37
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
38
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.PricingOperations = exports.CostCalculationResultSchema = exports.EnvironmentCostSchema = exports.ServerTypePriceSchema = void 0;
|
|
43
|
+
exports.parseHetznerPrice = parseHetznerPrice;
|
|
44
|
+
exports.extractServerTypePrice = extractServerTypePrice;
|
|
45
|
+
exports.buildPriceMap = buildPriceMap;
|
|
46
|
+
exports.getServerTypeMonthlyPrice = getServerTypeMonthlyPrice;
|
|
47
|
+
exports.calculateHourlyFromMonthly = calculateHourlyFromMonthly;
|
|
48
|
+
exports.calculateCosts = calculateCosts;
|
|
49
|
+
var zod_1 = require("zod");
|
|
50
|
+
var schemas_js_1 = require("./schemas.js");
|
|
6
51
|
/**
|
|
7
52
|
* Default fallback price for unknown server types (EUR/month)
|
|
8
53
|
* Conservative estimate based on Hetzner's smallest standard server
|
|
9
54
|
*/
|
|
10
|
-
|
|
55
|
+
var DEFAULT_FALLBACK_PRICE_MONTHLY = 5.0;
|
|
11
56
|
/**
|
|
12
57
|
* Hours per month for hourly cost calculation
|
|
13
58
|
* Using 730 hours (average month: 365.25 days * 24 hours / 12 months)
|
|
14
59
|
*/
|
|
15
|
-
|
|
60
|
+
var HOURS_PER_MONTH = 730;
|
|
16
61
|
// ============================================================================
|
|
17
62
|
// Zod Schemas for Cost Calculation
|
|
18
63
|
// ============================================================================
|
|
19
64
|
/**
|
|
20
65
|
* Schema for server type price entry
|
|
21
66
|
*/
|
|
22
|
-
|
|
23
|
-
serverType: z.string(),
|
|
24
|
-
priceMonthly: z.number().nonnegative(),
|
|
25
|
-
priceHourly: z.number().nonnegative(),
|
|
26
|
-
deprecated: z.boolean().optional().default(false),
|
|
67
|
+
exports.ServerTypePriceSchema = zod_1.z.object({
|
|
68
|
+
serverType: zod_1.z.string(),
|
|
69
|
+
priceMonthly: zod_1.z.number().nonnegative(),
|
|
70
|
+
priceHourly: zod_1.z.number().nonnegative(),
|
|
71
|
+
deprecated: zod_1.z.boolean().optional().default(false),
|
|
27
72
|
});
|
|
28
73
|
/**
|
|
29
74
|
* Schema for environment cost entry
|
|
30
75
|
*/
|
|
31
|
-
|
|
32
|
-
environmentId: z.string(),
|
|
33
|
-
environmentName: z.string(),
|
|
34
|
-
serverType: z.string(),
|
|
35
|
-
isRunning: z.boolean(),
|
|
36
|
-
costMonthly: z.number().nonnegative(),
|
|
37
|
-
costHourly: z.number().nonnegative(),
|
|
38
|
-
priceInfo: ServerTypePriceSchema.optional(),
|
|
76
|
+
exports.EnvironmentCostSchema = zod_1.z.object({
|
|
77
|
+
environmentId: zod_1.z.string(),
|
|
78
|
+
environmentName: zod_1.z.string(),
|
|
79
|
+
serverType: zod_1.z.string(),
|
|
80
|
+
isRunning: zod_1.z.boolean(),
|
|
81
|
+
costMonthly: zod_1.z.number().nonnegative(),
|
|
82
|
+
costHourly: zod_1.z.number().nonnegative(),
|
|
83
|
+
priceInfo: exports.ServerTypePriceSchema.optional(),
|
|
39
84
|
});
|
|
40
85
|
/**
|
|
41
86
|
* Schema for cost calculation result
|
|
42
87
|
*/
|
|
43
|
-
|
|
44
|
-
totalMonthly: z.number().nonnegative(),
|
|
45
|
-
totalHourly: z.number().nonnegative(),
|
|
46
|
-
runningEnvironmentCount: z.number().nonnegative().int(),
|
|
47
|
-
stoppedEnvironmentCount: z.number().nonnegative().int(),
|
|
48
|
-
unknownServerTypeCount: z.number().nonnegative().int(),
|
|
49
|
-
breakdown: z.array(EnvironmentCostSchema),
|
|
50
|
-
priceMap: z.custom(),
|
|
88
|
+
exports.CostCalculationResultSchema = zod_1.z.object({
|
|
89
|
+
totalMonthly: zod_1.z.number().nonnegative(),
|
|
90
|
+
totalHourly: zod_1.z.number().nonnegative(),
|
|
91
|
+
runningEnvironmentCount: zod_1.z.number().nonnegative().int(),
|
|
92
|
+
stoppedEnvironmentCount: zod_1.z.number().nonnegative().int(),
|
|
93
|
+
unknownServerTypeCount: zod_1.z.number().nonnegative().int(),
|
|
94
|
+
breakdown: zod_1.z.array(exports.EnvironmentCostSchema),
|
|
95
|
+
priceMap: zod_1.z.custom(),
|
|
51
96
|
});
|
|
52
97
|
// ============================================================================
|
|
53
98
|
// Cost Calculation Utilities
|
|
@@ -59,10 +104,10 @@ export const CostCalculationResultSchema = z.object({
|
|
|
59
104
|
* @param priceString - Price string from Hetzner API (gross field)
|
|
60
105
|
* @returns Price in EUR as number
|
|
61
106
|
*/
|
|
62
|
-
|
|
63
|
-
|
|
107
|
+
function parseHetznerPrice(priceString) {
|
|
108
|
+
var parsed = parseFloat(priceString);
|
|
64
109
|
if (isNaN(parsed)) {
|
|
65
|
-
console.warn(
|
|
110
|
+
console.warn("Failed to parse Hetzner price string: ".concat(priceString));
|
|
66
111
|
return 0;
|
|
67
112
|
}
|
|
68
113
|
return parsed;
|
|
@@ -74,20 +119,21 @@ export function parseHetznerPrice(priceString) {
|
|
|
74
119
|
* @param serverType - Hetzner server type object
|
|
75
120
|
* @returns Server type price info or undefined if pricing unavailable
|
|
76
121
|
*/
|
|
77
|
-
|
|
122
|
+
function extractServerTypePrice(serverType) {
|
|
123
|
+
var _a;
|
|
78
124
|
if (!serverType.prices || serverType.prices.length === 0) {
|
|
79
|
-
console.warn(
|
|
125
|
+
console.warn("Server type ".concat(serverType.name, " has no pricing information"));
|
|
80
126
|
return undefined;
|
|
81
127
|
}
|
|
82
128
|
// Use first price entry (Hetzner API returns location-agnostic pricing first)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
129
|
+
var priceEntry = serverType.prices[0];
|
|
130
|
+
var priceMonthly = parseHetznerPrice(priceEntry.price_monthly.gross);
|
|
131
|
+
var priceHourly = parseHetznerPrice(priceEntry.price_hourly.gross);
|
|
86
132
|
return {
|
|
87
133
|
serverType: serverType.name,
|
|
88
|
-
priceMonthly,
|
|
89
|
-
priceHourly,
|
|
90
|
-
deprecated: serverType.deprecated
|
|
134
|
+
priceMonthly: priceMonthly,
|
|
135
|
+
priceHourly: priceHourly,
|
|
136
|
+
deprecated: (_a = serverType.deprecated) !== null && _a !== void 0 ? _a : false,
|
|
91
137
|
};
|
|
92
138
|
}
|
|
93
139
|
/**
|
|
@@ -96,10 +142,11 @@ export function extractServerTypePrice(serverType) {
|
|
|
96
142
|
* @param serverTypes - Array of Hetzner server types
|
|
97
143
|
* @returns Map of server type name to price info
|
|
98
144
|
*/
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
for (
|
|
102
|
-
|
|
145
|
+
function buildPriceMap(serverTypes) {
|
|
146
|
+
var priceMap = new Map();
|
|
147
|
+
for (var _i = 0, serverTypes_1 = serverTypes; _i < serverTypes_1.length; _i++) {
|
|
148
|
+
var serverType = serverTypes_1[_i];
|
|
149
|
+
var priceInfo = extractServerTypePrice(serverType);
|
|
103
150
|
if (priceInfo) {
|
|
104
151
|
priceMap.set(serverType.name, priceInfo);
|
|
105
152
|
}
|
|
@@ -115,9 +162,11 @@ export function buildPriceMap(serverTypes) {
|
|
|
115
162
|
* @param fallbackPrice - Fallback price for unknown types (default: 5.0 EUR)
|
|
116
163
|
* @returns Monthly price in EUR
|
|
117
164
|
*/
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
165
|
+
function getServerTypeMonthlyPrice(serverTypeName, priceMap, fallbackPrice) {
|
|
166
|
+
var _a;
|
|
167
|
+
if (fallbackPrice === void 0) { fallbackPrice = DEFAULT_FALLBACK_PRICE_MONTHLY; }
|
|
168
|
+
var priceInfo = priceMap.get(serverTypeName);
|
|
169
|
+
return (_a = priceInfo === null || priceInfo === void 0 ? void 0 : priceInfo.priceMonthly) !== null && _a !== void 0 ? _a : fallbackPrice;
|
|
121
170
|
}
|
|
122
171
|
/**
|
|
123
172
|
* Calculate hourly price from monthly price
|
|
@@ -126,7 +175,7 @@ export function getServerTypeMonthlyPrice(serverTypeName, priceMap, fallbackPric
|
|
|
126
175
|
* @param monthlyPrice - Monthly price in EUR
|
|
127
176
|
* @returns Hourly price in EUR
|
|
128
177
|
*/
|
|
129
|
-
|
|
178
|
+
function calculateHourlyFromMonthly(monthlyPrice) {
|
|
130
179
|
return monthlyPrice / HOURS_PER_MONTH;
|
|
131
180
|
}
|
|
132
181
|
// ============================================================================
|
|
@@ -145,20 +194,23 @@ export function calculateHourlyFromMonthly(monthlyPrice) {
|
|
|
145
194
|
* @param options - Optional configuration
|
|
146
195
|
* @returns Cost calculation result with totals and breakdown
|
|
147
196
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
197
|
+
function calculateCosts(environments, serverTypes, options) {
|
|
198
|
+
var _a, _b;
|
|
199
|
+
if (options === void 0) { options = {}; }
|
|
200
|
+
var _c = options.fallbackPrice, fallbackPrice = _c === void 0 ? DEFAULT_FALLBACK_PRICE_MONTHLY : _c, _d = options.includeStopped, includeStopped = _d === void 0 ? false : _d;
|
|
150
201
|
// Build price lookup map
|
|
151
|
-
|
|
202
|
+
var priceMap = buildPriceMap(serverTypes);
|
|
152
203
|
// Calculate costs for each environment
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
for (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
204
|
+
var breakdown = [];
|
|
205
|
+
var totalMonthly = 0;
|
|
206
|
+
var runningCount = 0;
|
|
207
|
+
var stoppedCount = 0;
|
|
208
|
+
var unknownTypeCount = 0;
|
|
209
|
+
for (var _i = 0, environments_1 = environments; _i < environments_1.length; _i++) {
|
|
210
|
+
var env = environments_1[_i];
|
|
211
|
+
var isRunning = env.status === "running";
|
|
212
|
+
var priceInfo = priceMap.get(env.serverType);
|
|
213
|
+
var isUnknownType = !priceInfo;
|
|
162
214
|
// Count environments by status
|
|
163
215
|
if (isRunning) {
|
|
164
216
|
runningCount++;
|
|
@@ -171,11 +223,11 @@ export function calculateCosts(environments, serverTypes, options = {}) {
|
|
|
171
223
|
unknownTypeCount++;
|
|
172
224
|
}
|
|
173
225
|
// Get price (use fallback for unknown types, or 0 for stopped environments)
|
|
174
|
-
|
|
175
|
-
? (priceInfo
|
|
226
|
+
var monthlyPrice = isRunning
|
|
227
|
+
? ((_a = priceInfo === null || priceInfo === void 0 ? void 0 : priceInfo.priceMonthly) !== null && _a !== void 0 ? _a : fallbackPrice)
|
|
176
228
|
: 0;
|
|
177
|
-
|
|
178
|
-
? (priceInfo
|
|
229
|
+
var hourlyPrice = isRunning
|
|
230
|
+
? ((_b = priceInfo === null || priceInfo === void 0 ? void 0 : priceInfo.priceHourly) !== null && _b !== void 0 ? _b : calculateHourlyFromMonthly(fallbackPrice))
|
|
179
231
|
: 0;
|
|
180
232
|
// Add to totals (only running environments)
|
|
181
233
|
if (isRunning) {
|
|
@@ -187,7 +239,7 @@ export function calculateCosts(environments, serverTypes, options = {}) {
|
|
|
187
239
|
environmentId: env.id,
|
|
188
240
|
environmentName: env.name,
|
|
189
241
|
serverType: env.serverType,
|
|
190
|
-
isRunning,
|
|
242
|
+
isRunning: isRunning,
|
|
191
243
|
costMonthly: monthlyPrice,
|
|
192
244
|
costHourly: hourlyPrice,
|
|
193
245
|
priceInfo: priceInfo,
|
|
@@ -195,78 +247,119 @@ export function calculateCosts(environments, serverTypes, options = {}) {
|
|
|
195
247
|
}
|
|
196
248
|
}
|
|
197
249
|
// Calculate total hourly from monthly total
|
|
198
|
-
|
|
250
|
+
var totalHourly = calculateHourlyFromMonthly(totalMonthly);
|
|
199
251
|
return {
|
|
200
|
-
totalMonthly,
|
|
201
|
-
totalHourly,
|
|
252
|
+
totalMonthly: totalMonthly,
|
|
253
|
+
totalHourly: totalHourly,
|
|
202
254
|
runningEnvironmentCount: runningCount,
|
|
203
255
|
stoppedEnvironmentCount: stoppedCount,
|
|
204
256
|
unknownServerTypeCount: unknownTypeCount,
|
|
205
|
-
breakdown,
|
|
206
|
-
priceMap,
|
|
257
|
+
breakdown: breakdown,
|
|
258
|
+
priceMap: priceMap,
|
|
207
259
|
};
|
|
208
260
|
}
|
|
209
261
|
// ============================================================================
|
|
210
262
|
// Pricing Operations Class
|
|
211
263
|
// ============================================================================
|
|
212
|
-
|
|
213
|
-
client
|
|
214
|
-
constructor(client) {
|
|
264
|
+
var PricingOperations = /** @class */ (function () {
|
|
265
|
+
function PricingOperations(client) {
|
|
215
266
|
this.client = client;
|
|
216
267
|
}
|
|
217
268
|
/**
|
|
218
269
|
* List all server types
|
|
219
270
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
271
|
+
PricingOperations.prototype.listServerTypes = function () {
|
|
272
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
273
|
+
var response, validated;
|
|
274
|
+
return __generator(this, function (_a) {
|
|
275
|
+
switch (_a.label) {
|
|
276
|
+
case 0: return [4 /*yield*/, this.client.request("/server_types")];
|
|
277
|
+
case 1:
|
|
278
|
+
response = _a.sent();
|
|
279
|
+
validated = schemas_js_1.HetznerListServerTypesResponseSchema.safeParse(response);
|
|
280
|
+
if (!validated.success) {
|
|
281
|
+
console.warn('Hetzner list server types validation warning:', validated.error.issues);
|
|
282
|
+
return [2 /*return*/, response.server_types]; // Return unvalidated data for backward compatibility
|
|
283
|
+
}
|
|
284
|
+
return [2 /*return*/, validated.data.server_types];
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
};
|
|
230
289
|
/**
|
|
231
290
|
* Get a specific server type by name
|
|
232
291
|
*/
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
292
|
+
PricingOperations.prototype.getServerType = function (name) {
|
|
293
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
294
|
+
var types;
|
|
295
|
+
return __generator(this, function (_a) {
|
|
296
|
+
switch (_a.label) {
|
|
297
|
+
case 0: return [4 /*yield*/, this.listServerTypes()];
|
|
298
|
+
case 1:
|
|
299
|
+
types = _a.sent();
|
|
300
|
+
return [2 /*return*/, types.find(function (t) { return t.name === name; })];
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
};
|
|
237
305
|
/**
|
|
238
306
|
* List all locations
|
|
239
307
|
*/
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
308
|
+
PricingOperations.prototype.listLocations = function () {
|
|
309
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
310
|
+
var response, validated;
|
|
311
|
+
return __generator(this, function (_a) {
|
|
312
|
+
switch (_a.label) {
|
|
313
|
+
case 0: return [4 /*yield*/, this.client.request("/locations")];
|
|
314
|
+
case 1:
|
|
315
|
+
response = _a.sent();
|
|
316
|
+
validated = schemas_js_1.HetznerListLocationsResponseSchema.safeParse(response);
|
|
317
|
+
if (!validated.success) {
|
|
318
|
+
console.warn('Hetzner list locations validation warning:', validated.error.issues);
|
|
319
|
+
return [2 /*return*/, response.locations]; // Return unvalidated data for backward compatibility
|
|
320
|
+
}
|
|
321
|
+
return [2 /*return*/, validated.data.locations];
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
};
|
|
250
326
|
/**
|
|
251
327
|
* Get a specific location by name
|
|
252
328
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
329
|
+
PricingOperations.prototype.getLocation = function (name) {
|
|
330
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
331
|
+
var locations;
|
|
332
|
+
return __generator(this, function (_a) {
|
|
333
|
+
switch (_a.label) {
|
|
334
|
+
case 0: return [4 /*yield*/, this.listLocations()];
|
|
335
|
+
case 1:
|
|
336
|
+
locations = _a.sent();
|
|
337
|
+
return [2 /*return*/, locations.find(function (l) { return l.name === name; })];
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
};
|
|
257
342
|
/**
|
|
258
343
|
* List all datacenters
|
|
259
344
|
*/
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
345
|
+
PricingOperations.prototype.listDatacenters = function () {
|
|
346
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
347
|
+
var response, validated;
|
|
348
|
+
return __generator(this, function (_a) {
|
|
349
|
+
switch (_a.label) {
|
|
350
|
+
case 0: return [4 /*yield*/, this.client.request("/datacenters")];
|
|
351
|
+
case 1:
|
|
352
|
+
response = _a.sent();
|
|
353
|
+
validated = schemas_js_1.HetznerListDatacentersResponseSchema.safeParse(response);
|
|
354
|
+
if (!validated.success) {
|
|
355
|
+
console.warn('Hetzner list datacenters validation warning:', validated.error.issues);
|
|
356
|
+
return [2 /*return*/, response.datacenters]; // Return unvalidated data for backward compatibility
|
|
357
|
+
}
|
|
358
|
+
return [2 /*return*/, validated.data.datacenters];
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
};
|
|
270
363
|
/**
|
|
271
364
|
* Calculate costs for environments using current Hetzner pricing
|
|
272
365
|
*
|
|
@@ -276,9 +369,19 @@ export class PricingOperations {
|
|
|
276
369
|
* @param options - Optional configuration for cost calculation
|
|
277
370
|
* @returns Cost calculation result
|
|
278
371
|
*/
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
372
|
+
PricingOperations.prototype.calculateEnvironmentCosts = function (environments, options) {
|
|
373
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
374
|
+
var serverTypes;
|
|
375
|
+
return __generator(this, function (_a) {
|
|
376
|
+
switch (_a.label) {
|
|
377
|
+
case 0: return [4 /*yield*/, this.listServerTypes()];
|
|
378
|
+
case 1:
|
|
379
|
+
serverTypes = _a.sent();
|
|
380
|
+
return [2 /*return*/, calculateCosts(environments, serverTypes, options)];
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
return PricingOperations;
|
|
386
|
+
}());
|
|
387
|
+
exports.PricingOperations = PricingOperations;
|