@symbo.ls/sdk 2.33.26 → 2.33.27
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/dist/cjs/services/PlanService.js +90 -10
- package/dist/cjs/utils/services.js +1 -1
- package/dist/esm/index.js +91 -11
- package/dist/esm/services/PlanService.js +90 -10
- package/dist/esm/services/index.js +90 -10
- package/dist/esm/utils/services.js +1 -1
- package/dist/node/services/PlanService.js +90 -10
- package/dist/node/utils/services.js +1 -1
- package/package.json +7 -6
- package/src/services/PlanService.js +119 -14
- package/src/services/tests/PlanService/createPlan.test.js +92 -0
- package/src/services/tests/PlanService/createPlanWithValidation.test.js +177 -0
- package/src/services/tests/PlanService/deletePlan.test.js +92 -0
- package/src/services/tests/PlanService/getAdminPlans.test.js +84 -0
- package/src/services/tests/PlanService/getPlan.test.js +50 -0
- package/src/services/tests/PlanService/getPlanWithValidation.test.js +85 -0
- package/src/services/tests/PlanService/getPlans.test.js +53 -0
- package/src/services/tests/PlanService/getPlansWithValidation.test.js +48 -0
- package/src/services/tests/PlanService/initializePlans.test.js +75 -0
- package/src/services/tests/PlanService/updatePlan.test.js +111 -0
- package/src/services/tests/PlanService/updatePlanWithValidation.test.js +188 -0
- package/src/utils/services.js +1 -1
|
@@ -40,6 +40,23 @@ class PlanService extends import_BaseService.BaseService {
|
|
|
40
40
|
throw new Error(`Failed to get plans: ${error.message}`, { cause: error });
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Get list of public plans with enhanced pricing information (no authentication required)
|
|
45
|
+
*/
|
|
46
|
+
async getPlansWithPricing() {
|
|
47
|
+
try {
|
|
48
|
+
const response = await this._request("/plans/pricing", {
|
|
49
|
+
method: "GET",
|
|
50
|
+
methodName: "getPlansWithPricing"
|
|
51
|
+
});
|
|
52
|
+
if (response.success) {
|
|
53
|
+
return response.data;
|
|
54
|
+
}
|
|
55
|
+
throw new Error(response.message);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
throw new Error(`Failed to get plans with pricing: ${error.message}`, { cause: error });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
43
60
|
/**
|
|
44
61
|
* Get a specific plan by ID (no authentication required)
|
|
45
62
|
*/
|
|
@@ -204,16 +221,48 @@ class PlanService extends import_BaseService.BaseService {
|
|
|
204
221
|
if (!planData || typeof planData !== "object") {
|
|
205
222
|
throw new Error("Plan data must be a valid object");
|
|
206
223
|
}
|
|
207
|
-
const requiredFields = ["name", "
|
|
224
|
+
const requiredFields = ["name", "description"];
|
|
208
225
|
for (const field of requiredFields) {
|
|
209
226
|
if (!planData[field]) {
|
|
210
227
|
throw new Error(`Required field '${field}' is missing`);
|
|
211
228
|
}
|
|
212
229
|
}
|
|
213
|
-
if (
|
|
214
|
-
throw new Error("
|
|
230
|
+
if (Object.hasOwn(planData, "price")) {
|
|
231
|
+
throw new Error('Field "price" is no longer supported. Use unified "pricingOptions" with "amount" instead.');
|
|
232
|
+
}
|
|
233
|
+
if (planData.pricingOptions != null) {
|
|
234
|
+
if (!Array.isArray(planData.pricingOptions) || planData.pricingOptions.length === 0) {
|
|
235
|
+
throw new Error("pricingOptions must be a non-empty array when provided");
|
|
236
|
+
}
|
|
237
|
+
const allowedIntervals = /* @__PURE__ */ new Set(["month", "year", "week", "day", null]);
|
|
238
|
+
planData.pricingOptions.forEach((option, index) => {
|
|
239
|
+
if (!option || typeof option !== "object") {
|
|
240
|
+
throw new Error(`Pricing option at index ${index} must be an object`);
|
|
241
|
+
}
|
|
242
|
+
const { key, displayName, amount, interval, lookupKey } = option;
|
|
243
|
+
if (!key || typeof key !== "string") {
|
|
244
|
+
throw new Error(`Pricing option at index ${index} is missing required field 'key'`);
|
|
245
|
+
}
|
|
246
|
+
if (!/^[a-z0-9-]+$/u.test(key)) {
|
|
247
|
+
throw new Error(`Pricing option key '${key}' must contain only lowercase letters, numbers, and hyphens`);
|
|
248
|
+
}
|
|
249
|
+
if (!displayName || typeof displayName !== "string") {
|
|
250
|
+
throw new Error(`Pricing option '${key}' is missing required field 'displayName'`);
|
|
251
|
+
}
|
|
252
|
+
if (typeof amount !== "number" || amount < 0) {
|
|
253
|
+
throw new Error(`Pricing option '${key}' must have a non-negative numeric 'amount'`);
|
|
254
|
+
}
|
|
255
|
+
if (interval != null && !allowedIntervals.has(interval)) {
|
|
256
|
+
throw new Error(
|
|
257
|
+
`Pricing option '${key}' has invalid interval '${interval}'. Allowed: month, year, week, day or null`
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
if (!lookupKey || typeof lookupKey !== "string") {
|
|
261
|
+
throw new Error(`Pricing option '${key}' is missing required field 'lookupKey'`);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
215
264
|
}
|
|
216
|
-
if (!/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
265
|
+
if (planData.key && !/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
217
266
|
throw new Error("Plan key must contain only lowercase letters, numbers, and hyphens");
|
|
218
267
|
}
|
|
219
268
|
return await this.createPlan(planData);
|
|
@@ -228,10 +277,40 @@ class PlanService extends import_BaseService.BaseService {
|
|
|
228
277
|
if (!planData || typeof planData !== "object") {
|
|
229
278
|
throw new Error("Plan data must be a valid object");
|
|
230
279
|
}
|
|
231
|
-
if (planData
|
|
232
|
-
|
|
233
|
-
|
|
280
|
+
if (Object.hasOwn(planData, "price")) {
|
|
281
|
+
throw new Error('Field "price" is no longer supported. Use unified "pricingOptions" with "amount" instead.');
|
|
282
|
+
}
|
|
283
|
+
if (planData.pricingOptions != null) {
|
|
284
|
+
if (!Array.isArray(planData.pricingOptions) || planData.pricingOptions.length === 0) {
|
|
285
|
+
throw new Error("pricingOptions must be a non-empty array when provided");
|
|
234
286
|
}
|
|
287
|
+
const allowedIntervals = /* @__PURE__ */ new Set(["month", "year", "week", "day", null]);
|
|
288
|
+
planData.pricingOptions.forEach((option, index) => {
|
|
289
|
+
if (!option || typeof option !== "object") {
|
|
290
|
+
throw new Error(`Pricing option at index ${index} must be an object`);
|
|
291
|
+
}
|
|
292
|
+
const { key, displayName, amount, interval, lookupKey } = option;
|
|
293
|
+
if (!key || typeof key !== "string") {
|
|
294
|
+
throw new Error(`Pricing option at index ${index} is missing required field 'key'`);
|
|
295
|
+
}
|
|
296
|
+
if (!/^[a-z0-9-]+$/u.test(key)) {
|
|
297
|
+
throw new Error(`Pricing option key '${key}' must contain only lowercase letters, numbers, and hyphens`);
|
|
298
|
+
}
|
|
299
|
+
if (!displayName || typeof displayName !== "string") {
|
|
300
|
+
throw new Error(`Pricing option '${key}' is missing required field 'displayName'`);
|
|
301
|
+
}
|
|
302
|
+
if (typeof amount !== "number" || amount < 0) {
|
|
303
|
+
throw new Error(`Pricing option '${key}' must have a non-negative numeric 'amount'`);
|
|
304
|
+
}
|
|
305
|
+
if (interval != null && !allowedIntervals.has(interval)) {
|
|
306
|
+
throw new Error(
|
|
307
|
+
`Pricing option '${key}' has invalid interval '${interval}'. Allowed: month, year, week, day or null`
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
if (!lookupKey || typeof lookupKey !== "string") {
|
|
311
|
+
throw new Error(`Pricing option '${key}' is missing required field 'lookupKey'`);
|
|
312
|
+
}
|
|
313
|
+
});
|
|
235
314
|
}
|
|
236
315
|
if (planData.key && !/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
237
316
|
throw new Error("Plan key must contain only lowercase letters, numbers, and hyphens");
|
|
@@ -244,7 +323,7 @@ class PlanService extends import_BaseService.BaseService {
|
|
|
244
323
|
async getActivePlans() {
|
|
245
324
|
try {
|
|
246
325
|
const plans = await this.getPlans();
|
|
247
|
-
return plans.filter((plan) => plan.active !== false);
|
|
326
|
+
return plans.filter((plan) => plan.status === "active" && plan.isVisible !== false);
|
|
248
327
|
} catch (error) {
|
|
249
328
|
throw new Error(`Failed to get active plans: ${error.message}`, { cause: error });
|
|
250
329
|
}
|
|
@@ -254,9 +333,10 @@ class PlanService extends import_BaseService.BaseService {
|
|
|
254
333
|
*/
|
|
255
334
|
async getPlansByPriceRange(minPrice = 0, maxPrice = Infinity) {
|
|
256
335
|
try {
|
|
257
|
-
const plans = await this.
|
|
336
|
+
const plans = await this.getPlansWithPricing();
|
|
258
337
|
return plans.filter((plan) => {
|
|
259
|
-
|
|
338
|
+
var _a, _b;
|
|
339
|
+
const price = ((_b = (_a = plan == null ? void 0 : plan.pricing) == null ? void 0 : _a.bestPrice) == null ? void 0 : _b.amount) ?? 0;
|
|
260
340
|
return price >= minPrice && price <= maxPrice;
|
|
261
341
|
});
|
|
262
342
|
} catch (error) {
|
|
@@ -137,6 +137,7 @@ const SERVICE_METHODS = {
|
|
|
137
137
|
getActivePlans: "plan",
|
|
138
138
|
getPlansByPriceRange: "plan",
|
|
139
139
|
getPlanByKey: "plan",
|
|
140
|
+
getPlansWithPricing: "plan",
|
|
140
141
|
// Subscription methods (moved to subscription service)
|
|
141
142
|
createSubscription: "subscription",
|
|
142
143
|
getProjectStatus: "subscription",
|
|
@@ -186,7 +187,6 @@ const SERVICE_METHODS = {
|
|
|
186
187
|
createDnsRecordWithValidation: "dns",
|
|
187
188
|
getDnsRecordWithValidation: "dns",
|
|
188
189
|
removeDnsRecordWithValidation: "dns",
|
|
189
|
-
setProjectDomainsWithValidation: "dns",
|
|
190
190
|
addProjectCustomDomainsWithValidation: "dns",
|
|
191
191
|
isDomainAvailable: "dns",
|
|
192
192
|
getDomainStatus: "dns",
|
package/dist/esm/index.js
CHANGED
|
@@ -45037,6 +45037,23 @@ var PlanService = class extends BaseService {
|
|
|
45037
45037
|
throw new Error(`Failed to get plans: ${error.message}`, { cause: error });
|
|
45038
45038
|
}
|
|
45039
45039
|
}
|
|
45040
|
+
/**
|
|
45041
|
+
* Get list of public plans with enhanced pricing information (no authentication required)
|
|
45042
|
+
*/
|
|
45043
|
+
async getPlansWithPricing() {
|
|
45044
|
+
try {
|
|
45045
|
+
const response = await this._request("/plans/pricing", {
|
|
45046
|
+
method: "GET",
|
|
45047
|
+
methodName: "getPlansWithPricing"
|
|
45048
|
+
});
|
|
45049
|
+
if (response.success) {
|
|
45050
|
+
return response.data;
|
|
45051
|
+
}
|
|
45052
|
+
throw new Error(response.message);
|
|
45053
|
+
} catch (error) {
|
|
45054
|
+
throw new Error(`Failed to get plans with pricing: ${error.message}`, { cause: error });
|
|
45055
|
+
}
|
|
45056
|
+
}
|
|
45040
45057
|
/**
|
|
45041
45058
|
* Get a specific plan by ID (no authentication required)
|
|
45042
45059
|
*/
|
|
@@ -45201,16 +45218,48 @@ var PlanService = class extends BaseService {
|
|
|
45201
45218
|
if (!planData || typeof planData !== "object") {
|
|
45202
45219
|
throw new Error("Plan data must be a valid object");
|
|
45203
45220
|
}
|
|
45204
|
-
const requiredFields = ["name", "
|
|
45221
|
+
const requiredFields = ["name", "description"];
|
|
45205
45222
|
for (const field of requiredFields) {
|
|
45206
45223
|
if (!planData[field]) {
|
|
45207
45224
|
throw new Error(`Required field '${field}' is missing`);
|
|
45208
45225
|
}
|
|
45209
45226
|
}
|
|
45210
|
-
if (
|
|
45211
|
-
throw new Error("
|
|
45227
|
+
if (Object.hasOwn(planData, "price")) {
|
|
45228
|
+
throw new Error('Field "price" is no longer supported. Use unified "pricingOptions" with "amount" instead.');
|
|
45229
|
+
}
|
|
45230
|
+
if (planData.pricingOptions != null) {
|
|
45231
|
+
if (!Array.isArray(planData.pricingOptions) || planData.pricingOptions.length === 0) {
|
|
45232
|
+
throw new Error("pricingOptions must be a non-empty array when provided");
|
|
45233
|
+
}
|
|
45234
|
+
const allowedIntervals = /* @__PURE__ */ new Set(["month", "year", "week", "day", null]);
|
|
45235
|
+
planData.pricingOptions.forEach((option, index) => {
|
|
45236
|
+
if (!option || typeof option !== "object") {
|
|
45237
|
+
throw new Error(`Pricing option at index ${index} must be an object`);
|
|
45238
|
+
}
|
|
45239
|
+
const { key, displayName, amount, interval, lookupKey } = option;
|
|
45240
|
+
if (!key || typeof key !== "string") {
|
|
45241
|
+
throw new Error(`Pricing option at index ${index} is missing required field 'key'`);
|
|
45242
|
+
}
|
|
45243
|
+
if (!/^[a-z0-9-]+$/u.test(key)) {
|
|
45244
|
+
throw new Error(`Pricing option key '${key}' must contain only lowercase letters, numbers, and hyphens`);
|
|
45245
|
+
}
|
|
45246
|
+
if (!displayName || typeof displayName !== "string") {
|
|
45247
|
+
throw new Error(`Pricing option '${key}' is missing required field 'displayName'`);
|
|
45248
|
+
}
|
|
45249
|
+
if (typeof amount !== "number" || amount < 0) {
|
|
45250
|
+
throw new Error(`Pricing option '${key}' must have a non-negative numeric 'amount'`);
|
|
45251
|
+
}
|
|
45252
|
+
if (interval != null && !allowedIntervals.has(interval)) {
|
|
45253
|
+
throw new Error(
|
|
45254
|
+
`Pricing option '${key}' has invalid interval '${interval}'. Allowed: month, year, week, day or null`
|
|
45255
|
+
);
|
|
45256
|
+
}
|
|
45257
|
+
if (!lookupKey || typeof lookupKey !== "string") {
|
|
45258
|
+
throw new Error(`Pricing option '${key}' is missing required field 'lookupKey'`);
|
|
45259
|
+
}
|
|
45260
|
+
});
|
|
45212
45261
|
}
|
|
45213
|
-
if (!/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
45262
|
+
if (planData.key && !/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
45214
45263
|
throw new Error("Plan key must contain only lowercase letters, numbers, and hyphens");
|
|
45215
45264
|
}
|
|
45216
45265
|
return await this.createPlan(planData);
|
|
@@ -45225,10 +45274,40 @@ var PlanService = class extends BaseService {
|
|
|
45225
45274
|
if (!planData || typeof planData !== "object") {
|
|
45226
45275
|
throw new Error("Plan data must be a valid object");
|
|
45227
45276
|
}
|
|
45228
|
-
if (planData
|
|
45229
|
-
|
|
45230
|
-
|
|
45277
|
+
if (Object.hasOwn(planData, "price")) {
|
|
45278
|
+
throw new Error('Field "price" is no longer supported. Use unified "pricingOptions" with "amount" instead.');
|
|
45279
|
+
}
|
|
45280
|
+
if (planData.pricingOptions != null) {
|
|
45281
|
+
if (!Array.isArray(planData.pricingOptions) || planData.pricingOptions.length === 0) {
|
|
45282
|
+
throw new Error("pricingOptions must be a non-empty array when provided");
|
|
45231
45283
|
}
|
|
45284
|
+
const allowedIntervals = /* @__PURE__ */ new Set(["month", "year", "week", "day", null]);
|
|
45285
|
+
planData.pricingOptions.forEach((option, index) => {
|
|
45286
|
+
if (!option || typeof option !== "object") {
|
|
45287
|
+
throw new Error(`Pricing option at index ${index} must be an object`);
|
|
45288
|
+
}
|
|
45289
|
+
const { key, displayName, amount, interval, lookupKey } = option;
|
|
45290
|
+
if (!key || typeof key !== "string") {
|
|
45291
|
+
throw new Error(`Pricing option at index ${index} is missing required field 'key'`);
|
|
45292
|
+
}
|
|
45293
|
+
if (!/^[a-z0-9-]+$/u.test(key)) {
|
|
45294
|
+
throw new Error(`Pricing option key '${key}' must contain only lowercase letters, numbers, and hyphens`);
|
|
45295
|
+
}
|
|
45296
|
+
if (!displayName || typeof displayName !== "string") {
|
|
45297
|
+
throw new Error(`Pricing option '${key}' is missing required field 'displayName'`);
|
|
45298
|
+
}
|
|
45299
|
+
if (typeof amount !== "number" || amount < 0) {
|
|
45300
|
+
throw new Error(`Pricing option '${key}' must have a non-negative numeric 'amount'`);
|
|
45301
|
+
}
|
|
45302
|
+
if (interval != null && !allowedIntervals.has(interval)) {
|
|
45303
|
+
throw new Error(
|
|
45304
|
+
`Pricing option '${key}' has invalid interval '${interval}'. Allowed: month, year, week, day or null`
|
|
45305
|
+
);
|
|
45306
|
+
}
|
|
45307
|
+
if (!lookupKey || typeof lookupKey !== "string") {
|
|
45308
|
+
throw new Error(`Pricing option '${key}' is missing required field 'lookupKey'`);
|
|
45309
|
+
}
|
|
45310
|
+
});
|
|
45232
45311
|
}
|
|
45233
45312
|
if (planData.key && !/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
45234
45313
|
throw new Error("Plan key must contain only lowercase letters, numbers, and hyphens");
|
|
@@ -45241,7 +45320,7 @@ var PlanService = class extends BaseService {
|
|
|
45241
45320
|
async getActivePlans() {
|
|
45242
45321
|
try {
|
|
45243
45322
|
const plans = await this.getPlans();
|
|
45244
|
-
return plans.filter((plan) => plan.active !== false);
|
|
45323
|
+
return plans.filter((plan) => plan.status === "active" && plan.isVisible !== false);
|
|
45245
45324
|
} catch (error) {
|
|
45246
45325
|
throw new Error(`Failed to get active plans: ${error.message}`, { cause: error });
|
|
45247
45326
|
}
|
|
@@ -45251,9 +45330,10 @@ var PlanService = class extends BaseService {
|
|
|
45251
45330
|
*/
|
|
45252
45331
|
async getPlansByPriceRange(minPrice = 0, maxPrice = Infinity) {
|
|
45253
45332
|
try {
|
|
45254
|
-
const plans = await this.
|
|
45333
|
+
const plans = await this.getPlansWithPricing();
|
|
45255
45334
|
return plans.filter((plan) => {
|
|
45256
|
-
|
|
45335
|
+
var _a2, _b, _c;
|
|
45336
|
+
const price = (_c = (_b = (_a2 = plan == null ? void 0 : plan.pricing) == null ? void 0 : _a2.bestPrice) == null ? void 0 : _b.amount) != null ? _c : 0;
|
|
45257
45337
|
return price >= minPrice && price <= maxPrice;
|
|
45258
45338
|
});
|
|
45259
45339
|
} catch (error) {
|
|
@@ -48722,6 +48802,7 @@ var SERVICE_METHODS = {
|
|
|
48722
48802
|
getActivePlans: "plan",
|
|
48723
48803
|
getPlansByPriceRange: "plan",
|
|
48724
48804
|
getPlanByKey: "plan",
|
|
48805
|
+
getPlansWithPricing: "plan",
|
|
48725
48806
|
// Subscription methods (moved to subscription service)
|
|
48726
48807
|
createSubscription: "subscription",
|
|
48727
48808
|
getProjectStatus: "subscription",
|
|
@@ -48771,7 +48852,6 @@ var SERVICE_METHODS = {
|
|
|
48771
48852
|
createDnsRecordWithValidation: "dns",
|
|
48772
48853
|
getDnsRecordWithValidation: "dns",
|
|
48773
48854
|
removeDnsRecordWithValidation: "dns",
|
|
48774
|
-
setProjectDomainsWithValidation: "dns",
|
|
48775
48855
|
addProjectCustomDomainsWithValidation: "dns",
|
|
48776
48856
|
isDomainAvailable: "dns",
|
|
48777
48857
|
getDomainStatus: "dns",
|
|
@@ -817,6 +817,23 @@ var PlanService = class extends BaseService {
|
|
|
817
817
|
throw new Error(`Failed to get plans: ${error.message}`, { cause: error });
|
|
818
818
|
}
|
|
819
819
|
}
|
|
820
|
+
/**
|
|
821
|
+
* Get list of public plans with enhanced pricing information (no authentication required)
|
|
822
|
+
*/
|
|
823
|
+
async getPlansWithPricing() {
|
|
824
|
+
try {
|
|
825
|
+
const response = await this._request("/plans/pricing", {
|
|
826
|
+
method: "GET",
|
|
827
|
+
methodName: "getPlansWithPricing"
|
|
828
|
+
});
|
|
829
|
+
if (response.success) {
|
|
830
|
+
return response.data;
|
|
831
|
+
}
|
|
832
|
+
throw new Error(response.message);
|
|
833
|
+
} catch (error) {
|
|
834
|
+
throw new Error(`Failed to get plans with pricing: ${error.message}`, { cause: error });
|
|
835
|
+
}
|
|
836
|
+
}
|
|
820
837
|
/**
|
|
821
838
|
* Get a specific plan by ID (no authentication required)
|
|
822
839
|
*/
|
|
@@ -981,16 +998,48 @@ var PlanService = class extends BaseService {
|
|
|
981
998
|
if (!planData || typeof planData !== "object") {
|
|
982
999
|
throw new Error("Plan data must be a valid object");
|
|
983
1000
|
}
|
|
984
|
-
const requiredFields = ["name", "
|
|
1001
|
+
const requiredFields = ["name", "description"];
|
|
985
1002
|
for (const field of requiredFields) {
|
|
986
1003
|
if (!planData[field]) {
|
|
987
1004
|
throw new Error(`Required field '${field}' is missing`);
|
|
988
1005
|
}
|
|
989
1006
|
}
|
|
990
|
-
if (
|
|
991
|
-
throw new Error("
|
|
1007
|
+
if (Object.hasOwn(planData, "price")) {
|
|
1008
|
+
throw new Error('Field "price" is no longer supported. Use unified "pricingOptions" with "amount" instead.');
|
|
992
1009
|
}
|
|
993
|
-
if (
|
|
1010
|
+
if (planData.pricingOptions != null) {
|
|
1011
|
+
if (!Array.isArray(planData.pricingOptions) || planData.pricingOptions.length === 0) {
|
|
1012
|
+
throw new Error("pricingOptions must be a non-empty array when provided");
|
|
1013
|
+
}
|
|
1014
|
+
const allowedIntervals = /* @__PURE__ */ new Set(["month", "year", "week", "day", null]);
|
|
1015
|
+
planData.pricingOptions.forEach((option, index) => {
|
|
1016
|
+
if (!option || typeof option !== "object") {
|
|
1017
|
+
throw new Error(`Pricing option at index ${index} must be an object`);
|
|
1018
|
+
}
|
|
1019
|
+
const { key, displayName, amount, interval, lookupKey } = option;
|
|
1020
|
+
if (!key || typeof key !== "string") {
|
|
1021
|
+
throw new Error(`Pricing option at index ${index} is missing required field 'key'`);
|
|
1022
|
+
}
|
|
1023
|
+
if (!/^[a-z0-9-]+$/u.test(key)) {
|
|
1024
|
+
throw new Error(`Pricing option key '${key}' must contain only lowercase letters, numbers, and hyphens`);
|
|
1025
|
+
}
|
|
1026
|
+
if (!displayName || typeof displayName !== "string") {
|
|
1027
|
+
throw new Error(`Pricing option '${key}' is missing required field 'displayName'`);
|
|
1028
|
+
}
|
|
1029
|
+
if (typeof amount !== "number" || amount < 0) {
|
|
1030
|
+
throw new Error(`Pricing option '${key}' must have a non-negative numeric 'amount'`);
|
|
1031
|
+
}
|
|
1032
|
+
if (interval != null && !allowedIntervals.has(interval)) {
|
|
1033
|
+
throw new Error(
|
|
1034
|
+
`Pricing option '${key}' has invalid interval '${interval}'. Allowed: month, year, week, day or null`
|
|
1035
|
+
);
|
|
1036
|
+
}
|
|
1037
|
+
if (!lookupKey || typeof lookupKey !== "string") {
|
|
1038
|
+
throw new Error(`Pricing option '${key}' is missing required field 'lookupKey'`);
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
}
|
|
1042
|
+
if (planData.key && !/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
994
1043
|
throw new Error("Plan key must contain only lowercase letters, numbers, and hyphens");
|
|
995
1044
|
}
|
|
996
1045
|
return await this.createPlan(planData);
|
|
@@ -1005,10 +1054,40 @@ var PlanService = class extends BaseService {
|
|
|
1005
1054
|
if (!planData || typeof planData !== "object") {
|
|
1006
1055
|
throw new Error("Plan data must be a valid object");
|
|
1007
1056
|
}
|
|
1008
|
-
if (planData
|
|
1009
|
-
|
|
1010
|
-
|
|
1057
|
+
if (Object.hasOwn(planData, "price")) {
|
|
1058
|
+
throw new Error('Field "price" is no longer supported. Use unified "pricingOptions" with "amount" instead.');
|
|
1059
|
+
}
|
|
1060
|
+
if (planData.pricingOptions != null) {
|
|
1061
|
+
if (!Array.isArray(planData.pricingOptions) || planData.pricingOptions.length === 0) {
|
|
1062
|
+
throw new Error("pricingOptions must be a non-empty array when provided");
|
|
1011
1063
|
}
|
|
1064
|
+
const allowedIntervals = /* @__PURE__ */ new Set(["month", "year", "week", "day", null]);
|
|
1065
|
+
planData.pricingOptions.forEach((option, index) => {
|
|
1066
|
+
if (!option || typeof option !== "object") {
|
|
1067
|
+
throw new Error(`Pricing option at index ${index} must be an object`);
|
|
1068
|
+
}
|
|
1069
|
+
const { key, displayName, amount, interval, lookupKey } = option;
|
|
1070
|
+
if (!key || typeof key !== "string") {
|
|
1071
|
+
throw new Error(`Pricing option at index ${index} is missing required field 'key'`);
|
|
1072
|
+
}
|
|
1073
|
+
if (!/^[a-z0-9-]+$/u.test(key)) {
|
|
1074
|
+
throw new Error(`Pricing option key '${key}' must contain only lowercase letters, numbers, and hyphens`);
|
|
1075
|
+
}
|
|
1076
|
+
if (!displayName || typeof displayName !== "string") {
|
|
1077
|
+
throw new Error(`Pricing option '${key}' is missing required field 'displayName'`);
|
|
1078
|
+
}
|
|
1079
|
+
if (typeof amount !== "number" || amount < 0) {
|
|
1080
|
+
throw new Error(`Pricing option '${key}' must have a non-negative numeric 'amount'`);
|
|
1081
|
+
}
|
|
1082
|
+
if (interval != null && !allowedIntervals.has(interval)) {
|
|
1083
|
+
throw new Error(
|
|
1084
|
+
`Pricing option '${key}' has invalid interval '${interval}'. Allowed: month, year, week, day or null`
|
|
1085
|
+
);
|
|
1086
|
+
}
|
|
1087
|
+
if (!lookupKey || typeof lookupKey !== "string") {
|
|
1088
|
+
throw new Error(`Pricing option '${key}' is missing required field 'lookupKey'`);
|
|
1089
|
+
}
|
|
1090
|
+
});
|
|
1012
1091
|
}
|
|
1013
1092
|
if (planData.key && !/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
1014
1093
|
throw new Error("Plan key must contain only lowercase letters, numbers, and hyphens");
|
|
@@ -1021,7 +1100,7 @@ var PlanService = class extends BaseService {
|
|
|
1021
1100
|
async getActivePlans() {
|
|
1022
1101
|
try {
|
|
1023
1102
|
const plans = await this.getPlans();
|
|
1024
|
-
return plans.filter((plan) => plan.active !== false);
|
|
1103
|
+
return plans.filter((plan) => plan.status === "active" && plan.isVisible !== false);
|
|
1025
1104
|
} catch (error) {
|
|
1026
1105
|
throw new Error(`Failed to get active plans: ${error.message}`, { cause: error });
|
|
1027
1106
|
}
|
|
@@ -1031,9 +1110,10 @@ var PlanService = class extends BaseService {
|
|
|
1031
1110
|
*/
|
|
1032
1111
|
async getPlansByPriceRange(minPrice = 0, maxPrice = Infinity) {
|
|
1033
1112
|
try {
|
|
1034
|
-
const plans = await this.
|
|
1113
|
+
const plans = await this.getPlansWithPricing();
|
|
1035
1114
|
return plans.filter((plan) => {
|
|
1036
|
-
|
|
1115
|
+
var _a, _b, _c;
|
|
1116
|
+
const price = (_c = (_b = (_a = plan == null ? void 0 : plan.pricing) == null ? void 0 : _a.bestPrice) == null ? void 0 : _b.amount) != null ? _c : 0;
|
|
1037
1117
|
return price >= minPrice && price <= maxPrice;
|
|
1038
1118
|
});
|
|
1039
1119
|
} catch (error) {
|
|
@@ -45037,6 +45037,23 @@ var PlanService = class extends BaseService {
|
|
|
45037
45037
|
throw new Error(`Failed to get plans: ${error.message}`, { cause: error });
|
|
45038
45038
|
}
|
|
45039
45039
|
}
|
|
45040
|
+
/**
|
|
45041
|
+
* Get list of public plans with enhanced pricing information (no authentication required)
|
|
45042
|
+
*/
|
|
45043
|
+
async getPlansWithPricing() {
|
|
45044
|
+
try {
|
|
45045
|
+
const response = await this._request("/plans/pricing", {
|
|
45046
|
+
method: "GET",
|
|
45047
|
+
methodName: "getPlansWithPricing"
|
|
45048
|
+
});
|
|
45049
|
+
if (response.success) {
|
|
45050
|
+
return response.data;
|
|
45051
|
+
}
|
|
45052
|
+
throw new Error(response.message);
|
|
45053
|
+
} catch (error) {
|
|
45054
|
+
throw new Error(`Failed to get plans with pricing: ${error.message}`, { cause: error });
|
|
45055
|
+
}
|
|
45056
|
+
}
|
|
45040
45057
|
/**
|
|
45041
45058
|
* Get a specific plan by ID (no authentication required)
|
|
45042
45059
|
*/
|
|
@@ -45201,16 +45218,48 @@ var PlanService = class extends BaseService {
|
|
|
45201
45218
|
if (!planData || typeof planData !== "object") {
|
|
45202
45219
|
throw new Error("Plan data must be a valid object");
|
|
45203
45220
|
}
|
|
45204
|
-
const requiredFields = ["name", "
|
|
45221
|
+
const requiredFields = ["name", "description"];
|
|
45205
45222
|
for (const field of requiredFields) {
|
|
45206
45223
|
if (!planData[field]) {
|
|
45207
45224
|
throw new Error(`Required field '${field}' is missing`);
|
|
45208
45225
|
}
|
|
45209
45226
|
}
|
|
45210
|
-
if (
|
|
45211
|
-
throw new Error("
|
|
45227
|
+
if (Object.hasOwn(planData, "price")) {
|
|
45228
|
+
throw new Error('Field "price" is no longer supported. Use unified "pricingOptions" with "amount" instead.');
|
|
45229
|
+
}
|
|
45230
|
+
if (planData.pricingOptions != null) {
|
|
45231
|
+
if (!Array.isArray(planData.pricingOptions) || planData.pricingOptions.length === 0) {
|
|
45232
|
+
throw new Error("pricingOptions must be a non-empty array when provided");
|
|
45233
|
+
}
|
|
45234
|
+
const allowedIntervals = /* @__PURE__ */ new Set(["month", "year", "week", "day", null]);
|
|
45235
|
+
planData.pricingOptions.forEach((option, index) => {
|
|
45236
|
+
if (!option || typeof option !== "object") {
|
|
45237
|
+
throw new Error(`Pricing option at index ${index} must be an object`);
|
|
45238
|
+
}
|
|
45239
|
+
const { key, displayName, amount, interval, lookupKey } = option;
|
|
45240
|
+
if (!key || typeof key !== "string") {
|
|
45241
|
+
throw new Error(`Pricing option at index ${index} is missing required field 'key'`);
|
|
45242
|
+
}
|
|
45243
|
+
if (!/^[a-z0-9-]+$/u.test(key)) {
|
|
45244
|
+
throw new Error(`Pricing option key '${key}' must contain only lowercase letters, numbers, and hyphens`);
|
|
45245
|
+
}
|
|
45246
|
+
if (!displayName || typeof displayName !== "string") {
|
|
45247
|
+
throw new Error(`Pricing option '${key}' is missing required field 'displayName'`);
|
|
45248
|
+
}
|
|
45249
|
+
if (typeof amount !== "number" || amount < 0) {
|
|
45250
|
+
throw new Error(`Pricing option '${key}' must have a non-negative numeric 'amount'`);
|
|
45251
|
+
}
|
|
45252
|
+
if (interval != null && !allowedIntervals.has(interval)) {
|
|
45253
|
+
throw new Error(
|
|
45254
|
+
`Pricing option '${key}' has invalid interval '${interval}'. Allowed: month, year, week, day or null`
|
|
45255
|
+
);
|
|
45256
|
+
}
|
|
45257
|
+
if (!lookupKey || typeof lookupKey !== "string") {
|
|
45258
|
+
throw new Error(`Pricing option '${key}' is missing required field 'lookupKey'`);
|
|
45259
|
+
}
|
|
45260
|
+
});
|
|
45212
45261
|
}
|
|
45213
|
-
if (!/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
45262
|
+
if (planData.key && !/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
45214
45263
|
throw new Error("Plan key must contain only lowercase letters, numbers, and hyphens");
|
|
45215
45264
|
}
|
|
45216
45265
|
return await this.createPlan(planData);
|
|
@@ -45225,10 +45274,40 @@ var PlanService = class extends BaseService {
|
|
|
45225
45274
|
if (!planData || typeof planData !== "object") {
|
|
45226
45275
|
throw new Error("Plan data must be a valid object");
|
|
45227
45276
|
}
|
|
45228
|
-
if (planData
|
|
45229
|
-
|
|
45230
|
-
|
|
45277
|
+
if (Object.hasOwn(planData, "price")) {
|
|
45278
|
+
throw new Error('Field "price" is no longer supported. Use unified "pricingOptions" with "amount" instead.');
|
|
45279
|
+
}
|
|
45280
|
+
if (planData.pricingOptions != null) {
|
|
45281
|
+
if (!Array.isArray(planData.pricingOptions) || planData.pricingOptions.length === 0) {
|
|
45282
|
+
throw new Error("pricingOptions must be a non-empty array when provided");
|
|
45231
45283
|
}
|
|
45284
|
+
const allowedIntervals = /* @__PURE__ */ new Set(["month", "year", "week", "day", null]);
|
|
45285
|
+
planData.pricingOptions.forEach((option, index) => {
|
|
45286
|
+
if (!option || typeof option !== "object") {
|
|
45287
|
+
throw new Error(`Pricing option at index ${index} must be an object`);
|
|
45288
|
+
}
|
|
45289
|
+
const { key, displayName, amount, interval, lookupKey } = option;
|
|
45290
|
+
if (!key || typeof key !== "string") {
|
|
45291
|
+
throw new Error(`Pricing option at index ${index} is missing required field 'key'`);
|
|
45292
|
+
}
|
|
45293
|
+
if (!/^[a-z0-9-]+$/u.test(key)) {
|
|
45294
|
+
throw new Error(`Pricing option key '${key}' must contain only lowercase letters, numbers, and hyphens`);
|
|
45295
|
+
}
|
|
45296
|
+
if (!displayName || typeof displayName !== "string") {
|
|
45297
|
+
throw new Error(`Pricing option '${key}' is missing required field 'displayName'`);
|
|
45298
|
+
}
|
|
45299
|
+
if (typeof amount !== "number" || amount < 0) {
|
|
45300
|
+
throw new Error(`Pricing option '${key}' must have a non-negative numeric 'amount'`);
|
|
45301
|
+
}
|
|
45302
|
+
if (interval != null && !allowedIntervals.has(interval)) {
|
|
45303
|
+
throw new Error(
|
|
45304
|
+
`Pricing option '${key}' has invalid interval '${interval}'. Allowed: month, year, week, day or null`
|
|
45305
|
+
);
|
|
45306
|
+
}
|
|
45307
|
+
if (!lookupKey || typeof lookupKey !== "string") {
|
|
45308
|
+
throw new Error(`Pricing option '${key}' is missing required field 'lookupKey'`);
|
|
45309
|
+
}
|
|
45310
|
+
});
|
|
45232
45311
|
}
|
|
45233
45312
|
if (planData.key && !/^[a-z0-9-]+$/u.test(planData.key)) {
|
|
45234
45313
|
throw new Error("Plan key must contain only lowercase letters, numbers, and hyphens");
|
|
@@ -45241,7 +45320,7 @@ var PlanService = class extends BaseService {
|
|
|
45241
45320
|
async getActivePlans() {
|
|
45242
45321
|
try {
|
|
45243
45322
|
const plans = await this.getPlans();
|
|
45244
|
-
return plans.filter((plan) => plan.active !== false);
|
|
45323
|
+
return plans.filter((plan) => plan.status === "active" && plan.isVisible !== false);
|
|
45245
45324
|
} catch (error) {
|
|
45246
45325
|
throw new Error(`Failed to get active plans: ${error.message}`, { cause: error });
|
|
45247
45326
|
}
|
|
@@ -45251,9 +45330,10 @@ var PlanService = class extends BaseService {
|
|
|
45251
45330
|
*/
|
|
45252
45331
|
async getPlansByPriceRange(minPrice = 0, maxPrice = Infinity) {
|
|
45253
45332
|
try {
|
|
45254
|
-
const plans = await this.
|
|
45333
|
+
const plans = await this.getPlansWithPricing();
|
|
45255
45334
|
return plans.filter((plan) => {
|
|
45256
|
-
|
|
45335
|
+
var _a2, _b, _c;
|
|
45336
|
+
const price = (_c = (_b = (_a2 = plan == null ? void 0 : plan.pricing) == null ? void 0 : _a2.bestPrice) == null ? void 0 : _b.amount) != null ? _c : 0;
|
|
45257
45337
|
return price >= minPrice && price <= maxPrice;
|
|
45258
45338
|
});
|
|
45259
45339
|
} catch (error) {
|
|
@@ -116,6 +116,7 @@ var SERVICE_METHODS = {
|
|
|
116
116
|
getActivePlans: "plan",
|
|
117
117
|
getPlansByPriceRange: "plan",
|
|
118
118
|
getPlanByKey: "plan",
|
|
119
|
+
getPlansWithPricing: "plan",
|
|
119
120
|
// Subscription methods (moved to subscription service)
|
|
120
121
|
createSubscription: "subscription",
|
|
121
122
|
getProjectStatus: "subscription",
|
|
@@ -165,7 +166,6 @@ var SERVICE_METHODS = {
|
|
|
165
166
|
createDnsRecordWithValidation: "dns",
|
|
166
167
|
getDnsRecordWithValidation: "dns",
|
|
167
168
|
removeDnsRecordWithValidation: "dns",
|
|
168
|
-
setProjectDomainsWithValidation: "dns",
|
|
169
169
|
addProjectCustomDomainsWithValidation: "dns",
|
|
170
170
|
isDomainAvailable: "dns",
|
|
171
171
|
getDomainStatus: "dns",
|