@roxyon/api-client 0.3.0 → 0.5.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.d.cts CHANGED
@@ -59,6 +59,9 @@ declare class RoxyonClient {
59
59
  private sessionToken?;
60
60
  private anon?;
61
61
  constructor(opts?: RoxyonClientOptions);
62
+ /** Same endpoints and app, no user credentials: for public reads (catalog, quotes)
63
+ * that must work for PAT callers too, whose token the BaaS does not accept. */
64
+ publicClient(): RoxyonClient;
62
65
  getSessionToken(): string | undefined;
63
66
  setSessionToken(token: string | undefined): void;
64
67
  /** Mint (or reuse) an anonymous access token from the public app credentials. */
@@ -78,7 +81,8 @@ declare class RoxyonClient {
78
81
  del<T = unknown>(path: string, body?: unknown, opts?: RequestOptions): Promise<T>;
79
82
  }
80
83
 
81
- type TokenScope = 'deploy' | 'logs' | 'read';
84
+ /** `billing:order` lets the token place orders (human pays) within its monthly budget; never a default. */
85
+ type TokenScope = 'deploy' | 'logs' | 'read' | 'billing:order';
82
86
  interface TokenSummary {
83
87
  id: string;
84
88
  name: string;
@@ -87,6 +91,10 @@ interface TokenSummary {
87
91
  lastUsedAt: string | null;
88
92
  expiresAt: string | null;
89
93
  createdAt: string;
94
+ /** For `billing:order` tokens: the most it may order per calendar month, in USD before tax. */
95
+ monthlyBudgetUSD?: number | null;
96
+ /** For `billing:order` tokens: plan codes it may order (empty = any). */
97
+ allowedSkus?: string[];
90
98
  }
91
99
  interface CreatedToken {
92
100
  /** The full `roxp_…` secret — shown once. Use it as `ROXYON_TOKEN`. */
@@ -109,6 +117,9 @@ declare class TokensApi {
109
117
  create(name: string, opts?: {
110
118
  scopes?: TokenScope[];
111
119
  expiresInDays?: number;
120
+ /** Required with `billing:order`. */
121
+ monthlyBudgetUSD?: number;
122
+ allowedSkus?: string[];
112
123
  }): Promise<CreatedToken>;
113
124
  revoke(id: string): Promise<void>;
114
125
  }
@@ -364,6 +375,155 @@ declare class AuthApi {
364
375
  logout(): Promise<void>;
365
376
  }
366
377
 
378
+ /** Billing cycles the checkout accepts (Pricing::CYCLE_MONTHS). */
379
+ declare const BILLING_CYCLES: readonly ["monthly", "quarterly", "yearly", "biennial"];
380
+ type BillingCycle = (typeof BILLING_CYCLES)[number];
381
+ interface CatalogProduct {
382
+ /** Plan objectId: what quotes and orders take. */
383
+ planId: string;
384
+ /** Plan code, e.g. `SCALE-S`. */
385
+ sku: string;
386
+ name: string;
387
+ /** Service type, e.g. `cloud.vps.scale`, `cloud.hosting.solo`. */
388
+ category: string;
389
+ vcpu?: number;
390
+ ramGb?: number;
391
+ diskGb?: number;
392
+ cpuType?: string;
393
+ /** Dedicated IPv4 addresses included (servers). */
394
+ ipv4Included?: number;
395
+ /** List prices in USD before tax, per cycle. Quote for the buyer's currency and tax. */
396
+ pricesUSD: Partial<Record<BillingCycle, number>>;
397
+ /** Setup fee in USD per cycle, when not zero. */
398
+ setupFeeUSD?: Partial<Record<BillingCycle, number>>;
399
+ /** `out` = cannot be ordered right now. */
400
+ stock: 'in' | 'out';
401
+ /** Feature table as the console shows it. */
402
+ features?: Record<string, unknown>;
403
+ }
404
+ interface QuoteInput {
405
+ planId: string;
406
+ cycle: BillingCycle;
407
+ /** ISO 4217, e.g. `SAR`. Default USD. */
408
+ currency?: string;
409
+ /** ISO 3166 alpha-2, decides tax (e.g. `SA` = 15% VAT). Empty = no tax line. */
410
+ country?: string;
411
+ }
412
+ interface Quote {
413
+ planId: string;
414
+ cycle: string;
415
+ currency: string;
416
+ lineItems: Array<{
417
+ label: string;
418
+ amount: string;
419
+ amountUSD: string;
420
+ }>;
421
+ subtotal: string;
422
+ taxRate: string;
423
+ taxLabel: string;
424
+ taxAmount: string;
425
+ discountAmount: string;
426
+ total: string;
427
+ fxRate: string;
428
+ baseAmountUSD: string;
429
+ }
430
+ interface OrderInput {
431
+ /** Plan code from the catalog, e.g. `SCALE-S`. */
432
+ sku: string;
433
+ cycle: BillingCycle;
434
+ /** A name for the service. */
435
+ name: string;
436
+ /** Account / server name: 2-63 lowercase letters, digits, dots, dashes; must be free. */
437
+ username: string;
438
+ /** Servers only: OS image, e.g. `ubuntu-24.04`. */
439
+ image?: string;
440
+ sshKey?: string;
441
+ phpVersion?: string;
442
+ datacenter?: string;
443
+ currency?: string;
444
+ country?: string;
445
+ /** false/absent = dry run (quote + budget check, nothing written). */
446
+ confirm?: boolean;
447
+ }
448
+ interface OrderBudget {
449
+ monthlyUSD: number;
450
+ spentUSD: number;
451
+ remainingUSD: number;
452
+ }
453
+ interface OrderResult {
454
+ dryRun?: boolean;
455
+ plan: {
456
+ id: string;
457
+ sku: string;
458
+ name: string;
459
+ kind: 'hosting' | 'server';
460
+ cycle: string;
461
+ };
462
+ /** Dry run: the server quote (same shape as GET /_payment/quote). */
463
+ quote?: Record<string, unknown>;
464
+ subscriptionId?: string;
465
+ invoiceId?: string;
466
+ total?: string;
467
+ currency?: string;
468
+ payUrl?: string;
469
+ /** null for a console session (no token budget). */
470
+ budget: OrderBudget | null;
471
+ }
472
+ interface BillingSubscription {
473
+ id: string;
474
+ name: string;
475
+ status: string;
476
+ plan: string;
477
+ sku: string;
478
+ cycle: string;
479
+ price: string;
480
+ currency: string;
481
+ nextBillingDate: string | null;
482
+ autoRenew: boolean;
483
+ serverState: string | null;
484
+ publicIp: string | null;
485
+ }
486
+ interface Invoice {
487
+ id: string;
488
+ number: string;
489
+ type: string;
490
+ status: string;
491
+ total: string;
492
+ currency: string;
493
+ dueDate: string | null;
494
+ subscription: string | null;
495
+ createdAt: string;
496
+ payUrl: string | null;
497
+ }
498
+ /** Invoice statuses a customer can still pay. */
499
+ declare const PAYABLE_STATUSES: readonly ["pending", "overdue", "failed"];
500
+ declare function isPayable(status: string): boolean;
501
+ /**
502
+ * Catalog + quotes (public, no sign-in) and the caller's own subscriptions + invoices
503
+ * (console, session or PAT). Read-only: nothing here creates orders or invoices.
504
+ */
505
+ declare class BillingApi {
506
+ private readonly client;
507
+ private readonly pub;
508
+ constructor(client: RoxyonClient, pub?: RoxyonClient);
509
+ catalog(): Promise<CatalogProduct[]>;
510
+ /** What checkout would charge for a new subscription: the server's own pricing (GET /_payment/quote). */
511
+ quote(input: QuoteInput): Promise<Quote>;
512
+ /**
513
+ * A new order for the caller (POST /account/order): dry run unless `confirm`. The engine prices and creates it
514
+ * (Subscription in payment + pending invoice); a person pays at `payUrl`. Needs a session or a PAT with the
515
+ * `billing:order` scope, within that token's monthly budget and allowed SKUs.
516
+ */
517
+ order(input: OrderInput): Promise<OrderResult>;
518
+ /** The caller's own subscriptions (rows they own), newest first. */
519
+ subscriptions(): Promise<BillingSubscription[]>;
520
+ /** The caller's own invoices, newest first. */
521
+ invoices(opts?: {
522
+ status?: string;
523
+ limit?: number;
524
+ }): Promise<Invoice[]>;
525
+ }
526
+
367
527
  interface CreateDatabaseInput {
368
528
  /** DB name suffix — the platform prefixes it with the subscription's own username (globally unique). */
369
529
  name: string;
@@ -586,6 +746,76 @@ declare class SubscriptionsApi {
586
746
  resolve(userId: string, preferred?: string): Promise<Subscription>;
587
747
  }
588
748
 
749
+ /** BaaS V2 base. V1 (`/1`) is frozen; app data tools speak V2 only. */
750
+ declare const DEFAULT_BAAS_V2_URL = "https://www.beaapis.com/2";
751
+ /** V2 caps one page at 200 rows. */
752
+ declare const BAAS_MAX_PAGE = 200;
753
+ /** V2 takes 1 to 50 requests per batch. */
754
+ declare const BAAS_MAX_BATCH = 50;
755
+ interface BaasDataOptions {
756
+ /** The app's secret key (`rxsk_…`): server scope, from the project's API keys in Roxyon Base. */
757
+ secretKey: string;
758
+ baseUrl?: string;
759
+ fetch?: typeof fetch;
760
+ }
761
+ type BaasRow = Record<string, unknown>;
762
+ interface BaasQuery {
763
+ /** e.g. `{ Status: 'active', Age: { gt: 18 } }`; `in` takes a comma-joined string. */
764
+ where?: Record<string, unknown>;
765
+ /** `*` and/or column names, comma separated. Defaults to `*`. */
766
+ fields?: string;
767
+ /** Comma list, `-` for descending, e.g. `-createdAt`. */
768
+ order?: string;
769
+ /** 1 to 200 (default 50). */
770
+ limit?: number;
771
+ skip?: number;
772
+ /** Also return the total number of matching rows. */
773
+ count?: boolean;
774
+ }
775
+ interface BaasBatchRequest {
776
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
777
+ /** `/Class` or `/Class/<id>`. */
778
+ path: string;
779
+ body?: Record<string, unknown>;
780
+ }
781
+ /** One batch answer: `ok:false` with `error`/`message`, or that request's own V2 answer. */
782
+ interface BaasBatchResult {
783
+ status: number;
784
+ ok?: boolean;
785
+ error?: string;
786
+ message?: string;
787
+ result?: BaasRow;
788
+ results?: BaasRow[];
789
+ count?: number;
790
+ id?: string;
791
+ }
792
+ /**
793
+ * Records of ONE app on BaaS V2, as that app's own backend (server scope, `X-RX-Secret-Key`).
794
+ * Server scope passes every class rule, so treat the key like a database password. V2 answers
795
+ * failures as `{ok:false, error, message}` with an HTTP status; every call throws on those.
796
+ * Schema changes are not reachable with a secret key (console API only).
797
+ */
798
+ declare class BaasDataApi {
799
+ private readonly baseUrl;
800
+ private readonly secretKey;
801
+ private readonly _fetch;
802
+ constructor(opts: BaasDataOptions);
803
+ private call;
804
+ private static recordPath;
805
+ query(className: string, q?: BaasQuery): Promise<{
806
+ rows: BaasRow[];
807
+ count?: number;
808
+ }>;
809
+ get(className: string, objectId: string): Promise<BaasRow>;
810
+ /** Returns the created row as stored. */
811
+ create(className: string, data: BaasRow): Promise<BaasRow>;
812
+ update(className: string, objectId: string, data: BaasRow): Promise<BaasRow>;
813
+ /** The id goes in the URL path, never the body. */
814
+ delete(className: string, objectId: string): Promise<void>;
815
+ /** 1 to 50 record requests in one call; one failing doesn't stop the others. */
816
+ batch(requests: BaasBatchRequest[]): Promise<BaasBatchResult[]>;
817
+ }
818
+
589
819
  /** Returns the error message from a BaaS response, or `''` when the call worked. */
590
820
  declare function rxError(r: unknown): string;
591
821
  declare class RoxyonApiError extends Error {
@@ -695,8 +925,9 @@ declare class Roxyon {
695
925
  readonly databases: DatabasesApi;
696
926
  readonly email: EmailApi;
697
927
  readonly ssh: SshApi;
928
+ readonly billing: BillingApi;
698
929
  constructor(options?: RoxyonClientOptions | RoxyonClient);
699
930
  get sessionToken(): string | undefined;
700
931
  }
701
932
 
702
- export { AccountApi, type AccountApp, type AccountContext, type AccountDomain, type AccountSubscription, type Application, type ApplicationProcess, type ApplicationRoute, ApplicationsApi, AuthApi, type CreateApplicationInput, type CreateDatabaseInput, type CreateDatabaseResult, type CreateDomainInput, type CreateDomainResult, type CreateEmailInput, type CreateEmailResult, type CreateOnDeploy, type CreatedToken, DEFAULT_APP, DEFAULT_BAAS_URL, DEFAULT_CONSOLE_URL, type DatabaseSummary, DatabasesApi, type DeleteDatabaseResult, type DeleteEmailResult, type DeployKind, type DeployOptions, type DeployResult, type Domain, DomainsApi, EmailApi, type EmailSummary, LUMEN_BUILD, type LoginPrecheck, type LoginResult, type Privilege, RUNTIMES, type RequestOptions, type ResetSshPasswordInput, type ResetSshPasswordResult, Roxyon, RoxyonApiError, RoxyonClient, type RoxyonClientOptions, type RoxyonUser, type RuntimeName, type RuntimeSpec, type SessionGrant, type SiteFile, type SiteFileContent, SitesApi, SshApi, type StaticDeployResult, type Subscription, SubscriptionsApi, type TokenScope, type TokenSummary, TokensApi, assertOk, envFromStored, formatEnv, isAuthError, parseEnv, rxError, toQueryString };
933
+ export { AccountApi, type AccountApp, type AccountContext, type AccountDomain, type AccountSubscription, type Application, type ApplicationProcess, type ApplicationRoute, ApplicationsApi, AuthApi, BAAS_MAX_BATCH, BAAS_MAX_PAGE, BILLING_CYCLES, type BaasBatchRequest, type BaasBatchResult, BaasDataApi, type BaasDataOptions, type BaasQuery, type BaasRow, BillingApi, type BillingCycle, type BillingSubscription, type CatalogProduct, type CreateApplicationInput, type CreateDatabaseInput, type CreateDatabaseResult, type CreateDomainInput, type CreateDomainResult, type CreateEmailInput, type CreateEmailResult, type CreateOnDeploy, type CreatedToken, DEFAULT_APP, DEFAULT_BAAS_URL, DEFAULT_BAAS_V2_URL, DEFAULT_CONSOLE_URL, type DatabaseSummary, DatabasesApi, type DeleteDatabaseResult, type DeleteEmailResult, type DeployKind, type DeployOptions, type DeployResult, type Domain, DomainsApi, EmailApi, type EmailSummary, type Invoice, LUMEN_BUILD, type LoginPrecheck, type LoginResult, type OrderBudget, type OrderInput, type OrderResult, PAYABLE_STATUSES, type Privilege, type Quote, type QuoteInput, RUNTIMES, type RequestOptions, type ResetSshPasswordInput, type ResetSshPasswordResult, Roxyon, RoxyonApiError, RoxyonClient, type RoxyonClientOptions, type RoxyonUser, type RuntimeName, type RuntimeSpec, type SessionGrant, type SiteFile, type SiteFileContent, SitesApi, SshApi, type StaticDeployResult, type Subscription, SubscriptionsApi, type TokenScope, type TokenSummary, TokensApi, assertOk, envFromStored, formatEnv, isAuthError, isPayable, parseEnv, rxError, toQueryString };
package/dist/index.d.ts CHANGED
@@ -59,6 +59,9 @@ declare class RoxyonClient {
59
59
  private sessionToken?;
60
60
  private anon?;
61
61
  constructor(opts?: RoxyonClientOptions);
62
+ /** Same endpoints and app, no user credentials: for public reads (catalog, quotes)
63
+ * that must work for PAT callers too, whose token the BaaS does not accept. */
64
+ publicClient(): RoxyonClient;
62
65
  getSessionToken(): string | undefined;
63
66
  setSessionToken(token: string | undefined): void;
64
67
  /** Mint (or reuse) an anonymous access token from the public app credentials. */
@@ -78,7 +81,8 @@ declare class RoxyonClient {
78
81
  del<T = unknown>(path: string, body?: unknown, opts?: RequestOptions): Promise<T>;
79
82
  }
80
83
 
81
- type TokenScope = 'deploy' | 'logs' | 'read';
84
+ /** `billing:order` lets the token place orders (human pays) within its monthly budget; never a default. */
85
+ type TokenScope = 'deploy' | 'logs' | 'read' | 'billing:order';
82
86
  interface TokenSummary {
83
87
  id: string;
84
88
  name: string;
@@ -87,6 +91,10 @@ interface TokenSummary {
87
91
  lastUsedAt: string | null;
88
92
  expiresAt: string | null;
89
93
  createdAt: string;
94
+ /** For `billing:order` tokens: the most it may order per calendar month, in USD before tax. */
95
+ monthlyBudgetUSD?: number | null;
96
+ /** For `billing:order` tokens: plan codes it may order (empty = any). */
97
+ allowedSkus?: string[];
90
98
  }
91
99
  interface CreatedToken {
92
100
  /** The full `roxp_…` secret — shown once. Use it as `ROXYON_TOKEN`. */
@@ -109,6 +117,9 @@ declare class TokensApi {
109
117
  create(name: string, opts?: {
110
118
  scopes?: TokenScope[];
111
119
  expiresInDays?: number;
120
+ /** Required with `billing:order`. */
121
+ monthlyBudgetUSD?: number;
122
+ allowedSkus?: string[];
112
123
  }): Promise<CreatedToken>;
113
124
  revoke(id: string): Promise<void>;
114
125
  }
@@ -364,6 +375,155 @@ declare class AuthApi {
364
375
  logout(): Promise<void>;
365
376
  }
366
377
 
378
+ /** Billing cycles the checkout accepts (Pricing::CYCLE_MONTHS). */
379
+ declare const BILLING_CYCLES: readonly ["monthly", "quarterly", "yearly", "biennial"];
380
+ type BillingCycle = (typeof BILLING_CYCLES)[number];
381
+ interface CatalogProduct {
382
+ /** Plan objectId: what quotes and orders take. */
383
+ planId: string;
384
+ /** Plan code, e.g. `SCALE-S`. */
385
+ sku: string;
386
+ name: string;
387
+ /** Service type, e.g. `cloud.vps.scale`, `cloud.hosting.solo`. */
388
+ category: string;
389
+ vcpu?: number;
390
+ ramGb?: number;
391
+ diskGb?: number;
392
+ cpuType?: string;
393
+ /** Dedicated IPv4 addresses included (servers). */
394
+ ipv4Included?: number;
395
+ /** List prices in USD before tax, per cycle. Quote for the buyer's currency and tax. */
396
+ pricesUSD: Partial<Record<BillingCycle, number>>;
397
+ /** Setup fee in USD per cycle, when not zero. */
398
+ setupFeeUSD?: Partial<Record<BillingCycle, number>>;
399
+ /** `out` = cannot be ordered right now. */
400
+ stock: 'in' | 'out';
401
+ /** Feature table as the console shows it. */
402
+ features?: Record<string, unknown>;
403
+ }
404
+ interface QuoteInput {
405
+ planId: string;
406
+ cycle: BillingCycle;
407
+ /** ISO 4217, e.g. `SAR`. Default USD. */
408
+ currency?: string;
409
+ /** ISO 3166 alpha-2, decides tax (e.g. `SA` = 15% VAT). Empty = no tax line. */
410
+ country?: string;
411
+ }
412
+ interface Quote {
413
+ planId: string;
414
+ cycle: string;
415
+ currency: string;
416
+ lineItems: Array<{
417
+ label: string;
418
+ amount: string;
419
+ amountUSD: string;
420
+ }>;
421
+ subtotal: string;
422
+ taxRate: string;
423
+ taxLabel: string;
424
+ taxAmount: string;
425
+ discountAmount: string;
426
+ total: string;
427
+ fxRate: string;
428
+ baseAmountUSD: string;
429
+ }
430
+ interface OrderInput {
431
+ /** Plan code from the catalog, e.g. `SCALE-S`. */
432
+ sku: string;
433
+ cycle: BillingCycle;
434
+ /** A name for the service. */
435
+ name: string;
436
+ /** Account / server name: 2-63 lowercase letters, digits, dots, dashes; must be free. */
437
+ username: string;
438
+ /** Servers only: OS image, e.g. `ubuntu-24.04`. */
439
+ image?: string;
440
+ sshKey?: string;
441
+ phpVersion?: string;
442
+ datacenter?: string;
443
+ currency?: string;
444
+ country?: string;
445
+ /** false/absent = dry run (quote + budget check, nothing written). */
446
+ confirm?: boolean;
447
+ }
448
+ interface OrderBudget {
449
+ monthlyUSD: number;
450
+ spentUSD: number;
451
+ remainingUSD: number;
452
+ }
453
+ interface OrderResult {
454
+ dryRun?: boolean;
455
+ plan: {
456
+ id: string;
457
+ sku: string;
458
+ name: string;
459
+ kind: 'hosting' | 'server';
460
+ cycle: string;
461
+ };
462
+ /** Dry run: the server quote (same shape as GET /_payment/quote). */
463
+ quote?: Record<string, unknown>;
464
+ subscriptionId?: string;
465
+ invoiceId?: string;
466
+ total?: string;
467
+ currency?: string;
468
+ payUrl?: string;
469
+ /** null for a console session (no token budget). */
470
+ budget: OrderBudget | null;
471
+ }
472
+ interface BillingSubscription {
473
+ id: string;
474
+ name: string;
475
+ status: string;
476
+ plan: string;
477
+ sku: string;
478
+ cycle: string;
479
+ price: string;
480
+ currency: string;
481
+ nextBillingDate: string | null;
482
+ autoRenew: boolean;
483
+ serverState: string | null;
484
+ publicIp: string | null;
485
+ }
486
+ interface Invoice {
487
+ id: string;
488
+ number: string;
489
+ type: string;
490
+ status: string;
491
+ total: string;
492
+ currency: string;
493
+ dueDate: string | null;
494
+ subscription: string | null;
495
+ createdAt: string;
496
+ payUrl: string | null;
497
+ }
498
+ /** Invoice statuses a customer can still pay. */
499
+ declare const PAYABLE_STATUSES: readonly ["pending", "overdue", "failed"];
500
+ declare function isPayable(status: string): boolean;
501
+ /**
502
+ * Catalog + quotes (public, no sign-in) and the caller's own subscriptions + invoices
503
+ * (console, session or PAT). Read-only: nothing here creates orders or invoices.
504
+ */
505
+ declare class BillingApi {
506
+ private readonly client;
507
+ private readonly pub;
508
+ constructor(client: RoxyonClient, pub?: RoxyonClient);
509
+ catalog(): Promise<CatalogProduct[]>;
510
+ /** What checkout would charge for a new subscription: the server's own pricing (GET /_payment/quote). */
511
+ quote(input: QuoteInput): Promise<Quote>;
512
+ /**
513
+ * A new order for the caller (POST /account/order): dry run unless `confirm`. The engine prices and creates it
514
+ * (Subscription in payment + pending invoice); a person pays at `payUrl`. Needs a session or a PAT with the
515
+ * `billing:order` scope, within that token's monthly budget and allowed SKUs.
516
+ */
517
+ order(input: OrderInput): Promise<OrderResult>;
518
+ /** The caller's own subscriptions (rows they own), newest first. */
519
+ subscriptions(): Promise<BillingSubscription[]>;
520
+ /** The caller's own invoices, newest first. */
521
+ invoices(opts?: {
522
+ status?: string;
523
+ limit?: number;
524
+ }): Promise<Invoice[]>;
525
+ }
526
+
367
527
  interface CreateDatabaseInput {
368
528
  /** DB name suffix — the platform prefixes it with the subscription's own username (globally unique). */
369
529
  name: string;
@@ -586,6 +746,76 @@ declare class SubscriptionsApi {
586
746
  resolve(userId: string, preferred?: string): Promise<Subscription>;
587
747
  }
588
748
 
749
+ /** BaaS V2 base. V1 (`/1`) is frozen; app data tools speak V2 only. */
750
+ declare const DEFAULT_BAAS_V2_URL = "https://www.beaapis.com/2";
751
+ /** V2 caps one page at 200 rows. */
752
+ declare const BAAS_MAX_PAGE = 200;
753
+ /** V2 takes 1 to 50 requests per batch. */
754
+ declare const BAAS_MAX_BATCH = 50;
755
+ interface BaasDataOptions {
756
+ /** The app's secret key (`rxsk_…`): server scope, from the project's API keys in Roxyon Base. */
757
+ secretKey: string;
758
+ baseUrl?: string;
759
+ fetch?: typeof fetch;
760
+ }
761
+ type BaasRow = Record<string, unknown>;
762
+ interface BaasQuery {
763
+ /** e.g. `{ Status: 'active', Age: { gt: 18 } }`; `in` takes a comma-joined string. */
764
+ where?: Record<string, unknown>;
765
+ /** `*` and/or column names, comma separated. Defaults to `*`. */
766
+ fields?: string;
767
+ /** Comma list, `-` for descending, e.g. `-createdAt`. */
768
+ order?: string;
769
+ /** 1 to 200 (default 50). */
770
+ limit?: number;
771
+ skip?: number;
772
+ /** Also return the total number of matching rows. */
773
+ count?: boolean;
774
+ }
775
+ interface BaasBatchRequest {
776
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
777
+ /** `/Class` or `/Class/<id>`. */
778
+ path: string;
779
+ body?: Record<string, unknown>;
780
+ }
781
+ /** One batch answer: `ok:false` with `error`/`message`, or that request's own V2 answer. */
782
+ interface BaasBatchResult {
783
+ status: number;
784
+ ok?: boolean;
785
+ error?: string;
786
+ message?: string;
787
+ result?: BaasRow;
788
+ results?: BaasRow[];
789
+ count?: number;
790
+ id?: string;
791
+ }
792
+ /**
793
+ * Records of ONE app on BaaS V2, as that app's own backend (server scope, `X-RX-Secret-Key`).
794
+ * Server scope passes every class rule, so treat the key like a database password. V2 answers
795
+ * failures as `{ok:false, error, message}` with an HTTP status; every call throws on those.
796
+ * Schema changes are not reachable with a secret key (console API only).
797
+ */
798
+ declare class BaasDataApi {
799
+ private readonly baseUrl;
800
+ private readonly secretKey;
801
+ private readonly _fetch;
802
+ constructor(opts: BaasDataOptions);
803
+ private call;
804
+ private static recordPath;
805
+ query(className: string, q?: BaasQuery): Promise<{
806
+ rows: BaasRow[];
807
+ count?: number;
808
+ }>;
809
+ get(className: string, objectId: string): Promise<BaasRow>;
810
+ /** Returns the created row as stored. */
811
+ create(className: string, data: BaasRow): Promise<BaasRow>;
812
+ update(className: string, objectId: string, data: BaasRow): Promise<BaasRow>;
813
+ /** The id goes in the URL path, never the body. */
814
+ delete(className: string, objectId: string): Promise<void>;
815
+ /** 1 to 50 record requests in one call; one failing doesn't stop the others. */
816
+ batch(requests: BaasBatchRequest[]): Promise<BaasBatchResult[]>;
817
+ }
818
+
589
819
  /** Returns the error message from a BaaS response, or `''` when the call worked. */
590
820
  declare function rxError(r: unknown): string;
591
821
  declare class RoxyonApiError extends Error {
@@ -695,8 +925,9 @@ declare class Roxyon {
695
925
  readonly databases: DatabasesApi;
696
926
  readonly email: EmailApi;
697
927
  readonly ssh: SshApi;
928
+ readonly billing: BillingApi;
698
929
  constructor(options?: RoxyonClientOptions | RoxyonClient);
699
930
  get sessionToken(): string | undefined;
700
931
  }
701
932
 
702
- export { AccountApi, type AccountApp, type AccountContext, type AccountDomain, type AccountSubscription, type Application, type ApplicationProcess, type ApplicationRoute, ApplicationsApi, AuthApi, type CreateApplicationInput, type CreateDatabaseInput, type CreateDatabaseResult, type CreateDomainInput, type CreateDomainResult, type CreateEmailInput, type CreateEmailResult, type CreateOnDeploy, type CreatedToken, DEFAULT_APP, DEFAULT_BAAS_URL, DEFAULT_CONSOLE_URL, type DatabaseSummary, DatabasesApi, type DeleteDatabaseResult, type DeleteEmailResult, type DeployKind, type DeployOptions, type DeployResult, type Domain, DomainsApi, EmailApi, type EmailSummary, LUMEN_BUILD, type LoginPrecheck, type LoginResult, type Privilege, RUNTIMES, type RequestOptions, type ResetSshPasswordInput, type ResetSshPasswordResult, Roxyon, RoxyonApiError, RoxyonClient, type RoxyonClientOptions, type RoxyonUser, type RuntimeName, type RuntimeSpec, type SessionGrant, type SiteFile, type SiteFileContent, SitesApi, SshApi, type StaticDeployResult, type Subscription, SubscriptionsApi, type TokenScope, type TokenSummary, TokensApi, assertOk, envFromStored, formatEnv, isAuthError, parseEnv, rxError, toQueryString };
933
+ export { AccountApi, type AccountApp, type AccountContext, type AccountDomain, type AccountSubscription, type Application, type ApplicationProcess, type ApplicationRoute, ApplicationsApi, AuthApi, BAAS_MAX_BATCH, BAAS_MAX_PAGE, BILLING_CYCLES, type BaasBatchRequest, type BaasBatchResult, BaasDataApi, type BaasDataOptions, type BaasQuery, type BaasRow, BillingApi, type BillingCycle, type BillingSubscription, type CatalogProduct, type CreateApplicationInput, type CreateDatabaseInput, type CreateDatabaseResult, type CreateDomainInput, type CreateDomainResult, type CreateEmailInput, type CreateEmailResult, type CreateOnDeploy, type CreatedToken, DEFAULT_APP, DEFAULT_BAAS_URL, DEFAULT_BAAS_V2_URL, DEFAULT_CONSOLE_URL, type DatabaseSummary, DatabasesApi, type DeleteDatabaseResult, type DeleteEmailResult, type DeployKind, type DeployOptions, type DeployResult, type Domain, DomainsApi, EmailApi, type EmailSummary, type Invoice, LUMEN_BUILD, type LoginPrecheck, type LoginResult, type OrderBudget, type OrderInput, type OrderResult, PAYABLE_STATUSES, type Privilege, type Quote, type QuoteInput, RUNTIMES, type RequestOptions, type ResetSshPasswordInput, type ResetSshPasswordResult, Roxyon, RoxyonApiError, RoxyonClient, type RoxyonClientOptions, type RoxyonUser, type RuntimeName, type RuntimeSpec, type SessionGrant, type SiteFile, type SiteFileContent, SitesApi, SshApi, type StaticDeployResult, type Subscription, SubscriptionsApi, type TokenScope, type TokenSummary, TokensApi, assertOk, envFromStored, formatEnv, isAuthError, isPayable, parseEnv, rxError, toQueryString };