@roxyon/api-client 0.2.0 → 0.4.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/dist/index.cjs +392 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +294 -1
- package/dist/index.d.ts +294 -1
- package/dist/index.js +381 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -400,6 +400,144 @@ var AuthApi = class {
|
|
|
400
400
|
}
|
|
401
401
|
};
|
|
402
402
|
|
|
403
|
+
// src/billing.ts
|
|
404
|
+
var BILLING_CYCLES = ["monthly", "quarterly", "yearly", "biennial"];
|
|
405
|
+
var RESELLER_RESOLD_SERVICE_ID = "bjMqdLqAKl";
|
|
406
|
+
var PAYABLE_STATUSES = ["pending", "overdue", "failed"];
|
|
407
|
+
function isPayable(status) {
|
|
408
|
+
return PAYABLE_STATUSES.includes(status.toLowerCase());
|
|
409
|
+
}
|
|
410
|
+
function json(v, fallback) {
|
|
411
|
+
if (v && typeof v === "object") return v;
|
|
412
|
+
if (typeof v !== "string" || v === "") return fallback;
|
|
413
|
+
try {
|
|
414
|
+
return JSON.parse(v);
|
|
415
|
+
} catch {
|
|
416
|
+
return fallback;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function numbers(v) {
|
|
420
|
+
const out = {};
|
|
421
|
+
const src = json(v, {});
|
|
422
|
+
for (const c of BILLING_CYCLES) {
|
|
423
|
+
const n = Number(src[c]);
|
|
424
|
+
if (src[c] !== void 0 && src[c] !== "" && Number.isFinite(n)) out[c] = n;
|
|
425
|
+
}
|
|
426
|
+
return out;
|
|
427
|
+
}
|
|
428
|
+
var BillingApi = class {
|
|
429
|
+
constructor(client, pub = client.publicClient()) {
|
|
430
|
+
this.client = client;
|
|
431
|
+
this.pub = pub;
|
|
432
|
+
}
|
|
433
|
+
client;
|
|
434
|
+
pub;
|
|
435
|
+
async catalog() {
|
|
436
|
+
const r = await this.pub.get("/Plans", {
|
|
437
|
+
fields: "*",
|
|
438
|
+
limit: -1,
|
|
439
|
+
order: "objectId",
|
|
440
|
+
where: { Status: "active", Service: { nin: RESELLER_RESOLD_SERVICE_ID } },
|
|
441
|
+
include: [
|
|
442
|
+
{ className: "Services", field: "Service", fields: "Type" },
|
|
443
|
+
{
|
|
444
|
+
className: "Pricing",
|
|
445
|
+
field: "Plan",
|
|
446
|
+
fields: "Prices,SetupFee,MetaData",
|
|
447
|
+
reverse: 1
|
|
448
|
+
}
|
|
449
|
+
]
|
|
450
|
+
});
|
|
451
|
+
if (!Array.isArray(r.results)) {
|
|
452
|
+
throw new RoxyonApiError(r.error || "Could not load the catalog.", { body: r });
|
|
453
|
+
}
|
|
454
|
+
const out = [];
|
|
455
|
+
for (const p of r.results) {
|
|
456
|
+
const pricing = p._Pricing?.results?.[0];
|
|
457
|
+
if (!pricing) continue;
|
|
458
|
+
const limits = json(p.Limits, {});
|
|
459
|
+
const features = json(p.Features, {});
|
|
460
|
+
const meta = json(pricing.MetaData, {});
|
|
461
|
+
const network = json(features.Network, {});
|
|
462
|
+
const setup = numbers(pricing.SetupFee);
|
|
463
|
+
const product = {
|
|
464
|
+
planId: p.objectId,
|
|
465
|
+
sku: p.Code ?? "",
|
|
466
|
+
name: p.Name ?? "",
|
|
467
|
+
category: p._Service?.results?.[0]?.Type ?? "",
|
|
468
|
+
pricesUSD: numbers(pricing.Prices),
|
|
469
|
+
stock: String(meta.stock ?? "in").toLowerCase() === "out" ? "out" : "in"
|
|
470
|
+
};
|
|
471
|
+
if (limits.vcpu != null) {
|
|
472
|
+
product.vcpu = Number(limits.vcpu);
|
|
473
|
+
product.ramGb = limits.memory_mb ? Math.round(Number(limits.memory_mb) / 1024) : 0;
|
|
474
|
+
product.diskGb = Number(limits.disk_gb ?? 0);
|
|
475
|
+
product.cpuType = String(limits.cpu_type ?? "");
|
|
476
|
+
}
|
|
477
|
+
if (network["Dedicated IPv4"] != null)
|
|
478
|
+
product.ipv4Included = Number(network["Dedicated IPv4"]);
|
|
479
|
+
if (Object.values(setup).some((n) => n > 0)) product.setupFeeUSD = setup;
|
|
480
|
+
if (Object.keys(features).length) product.features = features;
|
|
481
|
+
out.push(product);
|
|
482
|
+
}
|
|
483
|
+
return out;
|
|
484
|
+
}
|
|
485
|
+
/** What checkout would charge for a new subscription: the server's own pricing (GET /_payment/quote). */
|
|
486
|
+
async quote(input) {
|
|
487
|
+
if (!/^[A-Za-z0-9]{1,40}$/.test(input.planId))
|
|
488
|
+
throw new Error(`Invalid planId "${input.planId}".`);
|
|
489
|
+
if (!BILLING_CYCLES.includes(input.cycle))
|
|
490
|
+
throw new Error(`Unsupported cycle "${input.cycle}".`);
|
|
491
|
+
const q = {
|
|
492
|
+
type: "subscription.new",
|
|
493
|
+
planId: input.planId,
|
|
494
|
+
cycle: input.cycle,
|
|
495
|
+
setup: 1
|
|
496
|
+
};
|
|
497
|
+
if (input.currency) q.currency = input.currency.toUpperCase();
|
|
498
|
+
if (input.country) q.country = input.country.toUpperCase();
|
|
499
|
+
const r = await this.pub.get("/_payment/quote", q);
|
|
500
|
+
if (!r?.ok) throw new RoxyonApiError(r?.error || "Could not price this plan.", { body: r });
|
|
501
|
+
return {
|
|
502
|
+
planId: String(r.planId ?? input.planId),
|
|
503
|
+
cycle: String(r.cycle ?? input.cycle),
|
|
504
|
+
currency: String(r.currency ?? ""),
|
|
505
|
+
lineItems: (r.lineItems ?? []).map((l) => ({
|
|
506
|
+
label: l.label,
|
|
507
|
+
amount: l.amount,
|
|
508
|
+
amountUSD: l.amountUSD
|
|
509
|
+
})),
|
|
510
|
+
subtotal: String(r.subtotal ?? ""),
|
|
511
|
+
taxRate: String(r.taxRate ?? ""),
|
|
512
|
+
taxLabel: String(r.taxLabel ?? ""),
|
|
513
|
+
taxAmount: String(r.taxAmount ?? ""),
|
|
514
|
+
discountAmount: String(r.discountAmount ?? ""),
|
|
515
|
+
total: String(r.total ?? ""),
|
|
516
|
+
fxRate: String(r.fxRate ?? ""),
|
|
517
|
+
baseAmountUSD: String(r.baseAmount ?? "")
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
/** The caller's own subscriptions (rows they own), newest first. */
|
|
521
|
+
async subscriptions() {
|
|
522
|
+
const r = await this.client.console("GET", "/account/subscriptions", { tolerateHttpError: true });
|
|
523
|
+
if (!r?.ok) throw new RoxyonApiError(r?.error || "Could not load subscriptions.", { body: r });
|
|
524
|
+
return r.subscriptions ?? [];
|
|
525
|
+
}
|
|
526
|
+
/** The caller's own invoices, newest first. */
|
|
527
|
+
async invoices(opts = {}) {
|
|
528
|
+
const q = {};
|
|
529
|
+
if (opts.status) q.status = opts.status;
|
|
530
|
+
if (opts.limit) q.limit = String(opts.limit);
|
|
531
|
+
const r = await this.client.console(
|
|
532
|
+
"GET",
|
|
533
|
+
"/account/invoices",
|
|
534
|
+
{ tolerateHttpError: true, query: q }
|
|
535
|
+
);
|
|
536
|
+
if (!r?.ok) throw new RoxyonApiError(r?.error || "Could not load invoices.", { body: r });
|
|
537
|
+
return (r.invoices ?? []).map((i) => ({ ...i, payUrl: isPayable(i.status) ? i.payUrl : null }));
|
|
538
|
+
}
|
|
539
|
+
};
|
|
540
|
+
|
|
403
541
|
// src/constants.ts
|
|
404
542
|
var DEFAULT_BAAS_URL = "https://www.beaapis.com/1";
|
|
405
543
|
var DEFAULT_CONSOLE_URL = "https://console.roxyon.com";
|
|
@@ -449,7 +587,7 @@ function toQueryString(query) {
|
|
|
449
587
|
}
|
|
450
588
|
|
|
451
589
|
// src/client.ts
|
|
452
|
-
var RoxyonClient = class {
|
|
590
|
+
var RoxyonClient = class _RoxyonClient {
|
|
453
591
|
baseUrl;
|
|
454
592
|
consoleUrl;
|
|
455
593
|
appId;
|
|
@@ -470,6 +608,17 @@ var RoxyonClient = class {
|
|
|
470
608
|
throw new Error("No fetch implementation available (need Node >= 20 or pass opts.fetch).");
|
|
471
609
|
}
|
|
472
610
|
}
|
|
611
|
+
/** Same endpoints and app, no user credentials: for public reads (catalog, quotes)
|
|
612
|
+
* that must work for PAT callers too, whose token the BaaS does not accept. */
|
|
613
|
+
publicClient() {
|
|
614
|
+
return new _RoxyonClient({
|
|
615
|
+
baseUrl: this.baseUrl,
|
|
616
|
+
consoleUrl: this.consoleUrl,
|
|
617
|
+
appId: this.appId,
|
|
618
|
+
javascriptKey: this.javascriptKey,
|
|
619
|
+
fetch: this._fetch
|
|
620
|
+
});
|
|
621
|
+
}
|
|
473
622
|
getSessionToken() {
|
|
474
623
|
return this.sessionToken;
|
|
475
624
|
}
|
|
@@ -490,16 +639,16 @@ var RoxyonClient = class {
|
|
|
490
639
|
},
|
|
491
640
|
body: JSON.stringify({ scope: "public" })
|
|
492
641
|
});
|
|
493
|
-
const
|
|
494
|
-
if (!
|
|
642
|
+
const json2 = await res.json().catch(() => ({}));
|
|
643
|
+
if (!json2.access_token && !json2.session_token) {
|
|
495
644
|
throw new RoxyonApiError("Could not obtain an anonymous BaaS token.", {
|
|
496
645
|
status: res.status,
|
|
497
|
-
body:
|
|
646
|
+
body: json2
|
|
498
647
|
});
|
|
499
648
|
}
|
|
500
|
-
|
|
501
|
-
this.anon =
|
|
502
|
-
return
|
|
649
|
+
json2._expiresAt = Date.now() + (json2.expires_in ? json2.expires_in * 1e3 : 36e5);
|
|
650
|
+
this.anon = json2;
|
|
651
|
+
return json2;
|
|
503
652
|
}
|
|
504
653
|
/** A Personal Access Token (`roxp_…`) authenticates the console endpoints via
|
|
505
654
|
* `Authorization: Bearer`; it is not a BaaS session token. */
|
|
@@ -549,17 +698,17 @@ var RoxyonClient = class {
|
|
|
549
698
|
throw new RoxyonApiError(`Network error calling ${method} ${url}`, { body: cause });
|
|
550
699
|
}
|
|
551
700
|
const text = await res.text();
|
|
552
|
-
let
|
|
701
|
+
let json2;
|
|
553
702
|
try {
|
|
554
|
-
|
|
703
|
+
json2 = text ? JSON.parse(text) : {};
|
|
555
704
|
} catch {
|
|
556
|
-
|
|
705
|
+
json2 = { error: text || `HTTP ${res.status}`, _raw: text };
|
|
557
706
|
}
|
|
558
707
|
if (!res.ok && !opts.tolerateHttpError) {
|
|
559
|
-
const msg =
|
|
560
|
-
throw new RoxyonApiError(String(msg), { status: res.status, body:
|
|
708
|
+
const msg = json2 && typeof json2 === "object" && "error" in json2 && json2.error || `HTTP ${res.status} calling ${method} ${path}`;
|
|
709
|
+
throw new RoxyonApiError(String(msg), { status: res.status, body: json2 });
|
|
561
710
|
}
|
|
562
|
-
return
|
|
711
|
+
return json2;
|
|
563
712
|
}
|
|
564
713
|
get(path, query, opts) {
|
|
565
714
|
return this.request("GET", path, { ...opts, query });
|
|
@@ -575,6 +724,41 @@ var RoxyonClient = class {
|
|
|
575
724
|
}
|
|
576
725
|
};
|
|
577
726
|
|
|
727
|
+
// src/databases.ts
|
|
728
|
+
var DatabasesApi = class {
|
|
729
|
+
constructor(client) {
|
|
730
|
+
this.client = client;
|
|
731
|
+
}
|
|
732
|
+
client;
|
|
733
|
+
async list(subscriptionId) {
|
|
734
|
+
const r = await this.client.get("/Databases", {
|
|
735
|
+
fields: "objectId,Name,Username,Status",
|
|
736
|
+
limit: -1,
|
|
737
|
+
order: "-createdAt",
|
|
738
|
+
where: { Subscription: subscriptionId, eye: { in: "1,0" } }
|
|
739
|
+
});
|
|
740
|
+
return r.results ?? [];
|
|
741
|
+
}
|
|
742
|
+
/** `POST /databases/create` — provision a database + user; the reconciler does the rest. */
|
|
743
|
+
async create(input) {
|
|
744
|
+
const r = await this.client.console("POST", "/databases/create", {
|
|
745
|
+
body: input,
|
|
746
|
+
tolerateHttpError: true
|
|
747
|
+
});
|
|
748
|
+
if (!r?.ok) throw new RoxyonApiError(r?.error || "Could not create the database.", { body: r });
|
|
749
|
+
return r;
|
|
750
|
+
}
|
|
751
|
+
/** `POST /databases/delete` */
|
|
752
|
+
async delete(databaseId) {
|
|
753
|
+
const r = await this.client.console("POST", "/databases/delete", {
|
|
754
|
+
body: { database: databaseId },
|
|
755
|
+
tolerateHttpError: true
|
|
756
|
+
});
|
|
757
|
+
if (!r?.ok) throw new RoxyonApiError(r?.error || "Could not delete the database.", { body: r });
|
|
758
|
+
return r;
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
|
|
578
762
|
// src/domains.ts
|
|
579
763
|
var DomainsApi = class {
|
|
580
764
|
constructor(client) {
|
|
@@ -605,6 +789,41 @@ var DomainsApi = class {
|
|
|
605
789
|
}
|
|
606
790
|
};
|
|
607
791
|
|
|
792
|
+
// src/email.ts
|
|
793
|
+
var EmailApi = class {
|
|
794
|
+
constructor(client) {
|
|
795
|
+
this.client = client;
|
|
796
|
+
}
|
|
797
|
+
client;
|
|
798
|
+
async list(subscriptionId) {
|
|
799
|
+
const r = await this.client.get("/Emails", {
|
|
800
|
+
fields: "objectId,Email,LocalPart,Status,Quota",
|
|
801
|
+
limit: -1,
|
|
802
|
+
order: "-createdAt",
|
|
803
|
+
where: { Subscription: subscriptionId, eye: { in: "1,0" } }
|
|
804
|
+
});
|
|
805
|
+
return r.results ?? [];
|
|
806
|
+
}
|
|
807
|
+
/** `POST /emails/create` — provision a mailbox; the reconciler does the rest. */
|
|
808
|
+
async create(input) {
|
|
809
|
+
const r = await this.client.console("POST", "/emails/create", {
|
|
810
|
+
body: input,
|
|
811
|
+
tolerateHttpError: true
|
|
812
|
+
});
|
|
813
|
+
if (!r?.ok) throw new RoxyonApiError(r?.error || "Could not create the mailbox.", { body: r });
|
|
814
|
+
return r;
|
|
815
|
+
}
|
|
816
|
+
/** `POST /emails/delete` */
|
|
817
|
+
async delete(emailId) {
|
|
818
|
+
const r = await this.client.console("POST", "/emails/delete", {
|
|
819
|
+
body: { email: emailId },
|
|
820
|
+
tolerateHttpError: true
|
|
821
|
+
});
|
|
822
|
+
if (!r?.ok) throw new RoxyonApiError(r?.error || "Could not delete the mailbox.", { body: r });
|
|
823
|
+
return r;
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
|
|
608
827
|
// src/sites.ts
|
|
609
828
|
var SitesApi = class {
|
|
610
829
|
constructor(client) {
|
|
@@ -649,6 +868,30 @@ var SitesApi = class {
|
|
|
649
868
|
}
|
|
650
869
|
};
|
|
651
870
|
|
|
871
|
+
// src/ssh.ts
|
|
872
|
+
var SshApi = class {
|
|
873
|
+
constructor(client) {
|
|
874
|
+
this.client = client;
|
|
875
|
+
}
|
|
876
|
+
client;
|
|
877
|
+
/** `POST /ssh/password` */
|
|
878
|
+
async resetPassword(input = {}) {
|
|
879
|
+
const r = await this.client.console("POST", "/ssh/password", {
|
|
880
|
+
body: input,
|
|
881
|
+
tolerateHttpError: true
|
|
882
|
+
});
|
|
883
|
+
if (!r?.ok) {
|
|
884
|
+
throw new RoxyonApiError(
|
|
885
|
+
r?.error || "Could not reset the password.",
|
|
886
|
+
{
|
|
887
|
+
body: r
|
|
888
|
+
}
|
|
889
|
+
);
|
|
890
|
+
}
|
|
891
|
+
return r;
|
|
892
|
+
}
|
|
893
|
+
};
|
|
894
|
+
|
|
652
895
|
// src/subscriptions.ts
|
|
653
896
|
var SubscriptionsApi = class {
|
|
654
897
|
constructor(client) {
|
|
@@ -748,6 +991,112 @@ var TokensApi = class {
|
|
|
748
991
|
}
|
|
749
992
|
};
|
|
750
993
|
|
|
994
|
+
// src/baas-data.ts
|
|
995
|
+
var DEFAULT_BAAS_V2_URL = "https://www.beaapis.com/2";
|
|
996
|
+
var BAAS_MAX_PAGE = 200;
|
|
997
|
+
var BAAS_MAX_BATCH = 50;
|
|
998
|
+
var CLASS_RE = /^[A-Za-z][A-Za-z0-9_]{0,63}$/;
|
|
999
|
+
var ID_RE = /^[A-Za-z0-9]{1,40}$/;
|
|
1000
|
+
function checkClass(name) {
|
|
1001
|
+
if (!CLASS_RE.test(name)) throw new Error(`Invalid class name "${name}".`);
|
|
1002
|
+
return name;
|
|
1003
|
+
}
|
|
1004
|
+
function checkId(id) {
|
|
1005
|
+
if (!ID_RE.test(id)) throw new Error(`Invalid objectId "${id}".`);
|
|
1006
|
+
return id;
|
|
1007
|
+
}
|
|
1008
|
+
var BaasDataApi = class _BaasDataApi {
|
|
1009
|
+
baseUrl;
|
|
1010
|
+
secretKey;
|
|
1011
|
+
_fetch;
|
|
1012
|
+
constructor(opts) {
|
|
1013
|
+
if (!opts.secretKey.startsWith("rxsk_")) {
|
|
1014
|
+
throw new Error("BaaS V2 needs the app secret key (starts with rxsk_).");
|
|
1015
|
+
}
|
|
1016
|
+
this.secretKey = opts.secretKey;
|
|
1017
|
+
this.baseUrl = (opts.baseUrl ?? DEFAULT_BAAS_V2_URL).replace(/\/+$/, "");
|
|
1018
|
+
this._fetch = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
1019
|
+
}
|
|
1020
|
+
async call(method, path, opts = {}) {
|
|
1021
|
+
const qs = opts.query && Object.keys(opts.query).length ? `?${new URLSearchParams(opts.query)}` : "";
|
|
1022
|
+
const headers = { "x-rx-secret-key": this.secretKey };
|
|
1023
|
+
if (opts.body !== void 0) headers["content-type"] = "application/json";
|
|
1024
|
+
let res;
|
|
1025
|
+
try {
|
|
1026
|
+
res = await this._fetch(`${this.baseUrl}${path}${qs}`, {
|
|
1027
|
+
method,
|
|
1028
|
+
headers,
|
|
1029
|
+
body: opts.body === void 0 ? void 0 : JSON.stringify(opts.body)
|
|
1030
|
+
});
|
|
1031
|
+
} catch (e) {
|
|
1032
|
+
throw new RoxyonApiError(`Could not reach ${this.baseUrl}: ${e.message}`);
|
|
1033
|
+
}
|
|
1034
|
+
let body = {};
|
|
1035
|
+
try {
|
|
1036
|
+
body = await res.json() ?? {};
|
|
1037
|
+
} catch {
|
|
1038
|
+
}
|
|
1039
|
+
if (!res.ok || body.ok !== true) {
|
|
1040
|
+
const msg = body.message || body.error || `HTTP ${res.status}`;
|
|
1041
|
+
throw new RoxyonApiError(msg, { status: res.status, type: body.error, body });
|
|
1042
|
+
}
|
|
1043
|
+
return body;
|
|
1044
|
+
}
|
|
1045
|
+
static recordPath(className, id) {
|
|
1046
|
+
return `/records/${checkClass(className)}${id === void 0 ? "" : `/${checkId(id)}`}`;
|
|
1047
|
+
}
|
|
1048
|
+
async query(className, q = {}) {
|
|
1049
|
+
const limit = q.limit ?? 50;
|
|
1050
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > BAAS_MAX_PAGE) {
|
|
1051
|
+
throw new Error(`limit must be 1 to ${BAAS_MAX_PAGE}.`);
|
|
1052
|
+
}
|
|
1053
|
+
const query = { fields: q.fields || "*", limit: String(limit) };
|
|
1054
|
+
if (q.where && Object.keys(q.where).length) query.where = JSON.stringify(q.where);
|
|
1055
|
+
if (q.order) query.order = q.order;
|
|
1056
|
+
if (q.skip) query.skip = String(q.skip);
|
|
1057
|
+
if (q.count) query.count = "1";
|
|
1058
|
+
const r = await this.call("GET", _BaasDataApi.recordPath(className), { query });
|
|
1059
|
+
return {
|
|
1060
|
+
rows: r.results ?? [],
|
|
1061
|
+
...r.count !== void 0 ? { count: r.count } : {}
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
async get(className, objectId) {
|
|
1065
|
+
const r = await this.call("GET", _BaasDataApi.recordPath(className, objectId));
|
|
1066
|
+
return r.result ?? {};
|
|
1067
|
+
}
|
|
1068
|
+
/** Returns the created row as stored. */
|
|
1069
|
+
async create(className, data) {
|
|
1070
|
+
const r = await this.call("POST", _BaasDataApi.recordPath(className), { body: { data } });
|
|
1071
|
+
return r.result ?? {};
|
|
1072
|
+
}
|
|
1073
|
+
async update(className, objectId, data) {
|
|
1074
|
+
const r = await this.call("PUT", _BaasDataApi.recordPath(className, objectId), {
|
|
1075
|
+
body: { data }
|
|
1076
|
+
});
|
|
1077
|
+
return r.result ?? {};
|
|
1078
|
+
}
|
|
1079
|
+
/** The id goes in the URL path, never the body. */
|
|
1080
|
+
async delete(className, objectId) {
|
|
1081
|
+
await this.call("DELETE", _BaasDataApi.recordPath(className, objectId));
|
|
1082
|
+
}
|
|
1083
|
+
/** 1 to 50 record requests in one call; one failing doesn't stop the others. */
|
|
1084
|
+
async batch(requests) {
|
|
1085
|
+
if (requests.length < 1 || requests.length > BAAS_MAX_BATCH) {
|
|
1086
|
+
throw new Error(`A batch takes 1 to ${BAAS_MAX_BATCH} requests.`);
|
|
1087
|
+
}
|
|
1088
|
+
for (const req of requests) {
|
|
1089
|
+
const [cls, id, extra] = req.path.split("/").filter(Boolean);
|
|
1090
|
+
if (!cls || extra !== void 0)
|
|
1091
|
+
throw new Error(`Batch path "${req.path}" must be /Class or /Class/id.`);
|
|
1092
|
+
checkClass(cls);
|
|
1093
|
+
if (id !== void 0) checkId(id);
|
|
1094
|
+
}
|
|
1095
|
+
const r = await this.call("POST", "/batch", { body: { requests } });
|
|
1096
|
+
return r.results ?? [];
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
|
|
751
1100
|
// src/env.ts
|
|
752
1101
|
function parseEnv(text) {
|
|
753
1102
|
const out = {};
|
|
@@ -824,6 +1173,10 @@ var Roxyon = class {
|
|
|
824
1173
|
domains;
|
|
825
1174
|
applications;
|
|
826
1175
|
sites;
|
|
1176
|
+
databases;
|
|
1177
|
+
email;
|
|
1178
|
+
ssh;
|
|
1179
|
+
billing;
|
|
827
1180
|
constructor(options = {}) {
|
|
828
1181
|
this.client = options instanceof RoxyonClient ? options : new RoxyonClient(options);
|
|
829
1182
|
this.auth = new AuthApi(this.client);
|
|
@@ -833,6 +1186,10 @@ var Roxyon = class {
|
|
|
833
1186
|
this.domains = new DomainsApi(this.client);
|
|
834
1187
|
this.applications = new ApplicationsApi(this.client);
|
|
835
1188
|
this.sites = new SitesApi(this.client);
|
|
1189
|
+
this.databases = new DatabasesApi(this.client);
|
|
1190
|
+
this.email = new EmailApi(this.client);
|
|
1191
|
+
this.ssh = new SshApi(this.client);
|
|
1192
|
+
this.billing = new BillingApi(this.client);
|
|
836
1193
|
}
|
|
837
1194
|
get sessionToken() {
|
|
838
1195
|
return this.client.getSessionToken();
|
|
@@ -842,22 +1199,33 @@ export {
|
|
|
842
1199
|
AccountApi,
|
|
843
1200
|
ApplicationsApi,
|
|
844
1201
|
AuthApi,
|
|
1202
|
+
BAAS_MAX_BATCH,
|
|
1203
|
+
BAAS_MAX_PAGE,
|
|
1204
|
+
BILLING_CYCLES,
|
|
1205
|
+
BaasDataApi,
|
|
1206
|
+
BillingApi,
|
|
845
1207
|
DEFAULT_APP,
|
|
846
1208
|
DEFAULT_BAAS_URL,
|
|
1209
|
+
DEFAULT_BAAS_V2_URL,
|
|
847
1210
|
DEFAULT_CONSOLE_URL,
|
|
1211
|
+
DatabasesApi,
|
|
848
1212
|
DomainsApi,
|
|
1213
|
+
EmailApi,
|
|
849
1214
|
LUMEN_BUILD,
|
|
1215
|
+
PAYABLE_STATUSES,
|
|
850
1216
|
RUNTIMES,
|
|
851
1217
|
Roxyon,
|
|
852
1218
|
RoxyonApiError,
|
|
853
1219
|
RoxyonClient,
|
|
854
1220
|
SitesApi,
|
|
1221
|
+
SshApi,
|
|
855
1222
|
SubscriptionsApi,
|
|
856
1223
|
TokensApi,
|
|
857
1224
|
assertOk,
|
|
858
1225
|
envFromStored,
|
|
859
1226
|
formatEnv,
|
|
860
1227
|
isAuthError,
|
|
1228
|
+
isPayable,
|
|
861
1229
|
parseEnv,
|
|
862
1230
|
rxError,
|
|
863
1231
|
toQueryString
|