@lizard-build/sdk 0.1.51 → 0.1.53
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.mts +186 -38
- package/dist/index.d.ts +186 -38
- package/dist/index.js +140 -114
- package/dist/index.mjs +139 -114
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1520,6 +1520,7 @@ declare class RegionsAPI {
|
|
|
1520
1520
|
list(): Promise<Region[]>;
|
|
1521
1521
|
}
|
|
1522
1522
|
|
|
1523
|
+
/** Prepaid credits balance: old credits accounts (`plan: 'payg'`) until 1 November 2026, and enterprise usage. */
|
|
1523
1524
|
interface Balance {
|
|
1524
1525
|
plan: string;
|
|
1525
1526
|
status: 'active' | 'grace' | 'frozen' | string;
|
|
@@ -1558,61 +1559,180 @@ interface ListTransactionsOpts {
|
|
|
1558
1559
|
includeUsage?: boolean;
|
|
1559
1560
|
}
|
|
1560
1561
|
/**
|
|
1561
|
-
*
|
|
1562
|
+
* `none`: no plan yet (creating anything answers 402). `pro`: the Pro subscription, see
|
|
1563
|
+
* {@link Subscription.status}. `payg`: old prepaid credits, until 1 November 2026.
|
|
1564
|
+
* `enterprise`: pay as you go, invoiced monthly.
|
|
1565
|
+
*/
|
|
1566
|
+
type Plan = 'none' | 'pro' | 'payg' | 'enterprise';
|
|
1567
|
+
/** Pro subscription status; `none` when there is no subscription. */
|
|
1568
|
+
type SubscriptionStatus = 'trialing' | 'active' | 'past_due' | 'canceled' | 'none';
|
|
1569
|
+
interface Subscription {
|
|
1570
|
+
plan: Plan | (string & {});
|
|
1571
|
+
status: SubscriptionStatus | (string & {});
|
|
1572
|
+
/** False when read for a workspace the caller does not own; card and invoice fields are then null. */
|
|
1573
|
+
isOwner: boolean;
|
|
1574
|
+
/** 1900: $19/month. */
|
|
1575
|
+
priceCents: number;
|
|
1576
|
+
/** The price includes taxes. */
|
|
1577
|
+
taxIncluded: boolean;
|
|
1578
|
+
/** Credits included each paid month, in cents (1900). */
|
|
1579
|
+
includedCents: number;
|
|
1580
|
+
trial: {
|
|
1581
|
+
/** The account can start a trial now. */
|
|
1582
|
+
eligible: boolean;
|
|
1583
|
+
/** Trial length it would get, or got. */
|
|
1584
|
+
days: number | null;
|
|
1585
|
+
/** Trial credits, in cents. */
|
|
1586
|
+
creditCents: number | null;
|
|
1587
|
+
/** Promo code held for the trial, if any. */
|
|
1588
|
+
promoCode: string | null;
|
|
1589
|
+
/** Trial end (ms); null when not trialing. */
|
|
1590
|
+
endsAt: number | null;
|
|
1591
|
+
/** Trial credits used (trialing only). */
|
|
1592
|
+
usedCents: number | null;
|
|
1593
|
+
remainingCents: number | null;
|
|
1594
|
+
};
|
|
1595
|
+
/** The current Pro period; null when there is none. */
|
|
1596
|
+
period: {
|
|
1597
|
+
kind: 'trial' | 'paid';
|
|
1598
|
+
start: number;
|
|
1599
|
+
end: number;
|
|
1600
|
+
/** 500 in the trial, 1900 in a paid month. */
|
|
1601
|
+
includedCents: number;
|
|
1602
|
+
usedCents: number;
|
|
1603
|
+
/** Paid month: usage above the included credits. */
|
|
1604
|
+
overageCents: number;
|
|
1605
|
+
/** Of the overage, already invoiced. */
|
|
1606
|
+
billedOverageCents: number;
|
|
1607
|
+
unbilledOverageCents: number;
|
|
1608
|
+
/** Paid month: unbilled overage at which the next invoice goes out. */
|
|
1609
|
+
nextOverageChargeAtCents: number | null;
|
|
1610
|
+
} | null;
|
|
1611
|
+
/** Null when there is none, or the subscription is cancelling. */
|
|
1612
|
+
nextCharge: {
|
|
1613
|
+
at: number | null;
|
|
1614
|
+
amountCents: number;
|
|
1615
|
+
} | null;
|
|
1616
|
+
/** When a cancelled subscription ends (ms). */
|
|
1617
|
+
cancelAt: number | null;
|
|
1618
|
+
/** An invoice is unpaid. */
|
|
1619
|
+
pastDue: boolean;
|
|
1620
|
+
/** Stripe page that pays it (owner only). */
|
|
1621
|
+
openInvoiceUrl: string | null;
|
|
1622
|
+
paymentMethod: {
|
|
1623
|
+
brand: string;
|
|
1624
|
+
last4: string;
|
|
1625
|
+
expMonth: number;
|
|
1626
|
+
expYear: number;
|
|
1627
|
+
} | null;
|
|
1628
|
+
/** Pro only: `tier` is `trial` or `pro`. */
|
|
1629
|
+
limits: {
|
|
1630
|
+
tier: string;
|
|
1631
|
+
replicasPerApp: number;
|
|
1632
|
+
} | null;
|
|
1633
|
+
/** Pro Checkout is open for this account. */
|
|
1634
|
+
checkoutAvailable: boolean;
|
|
1635
|
+
}
|
|
1636
|
+
interface StartCheckoutOpts {
|
|
1637
|
+
/** Dashboard path to come back to after Checkout, e.g. `/projects/abc`. */
|
|
1638
|
+
returnUrl?: string;
|
|
1639
|
+
}
|
|
1640
|
+
interface CheckoutSession {
|
|
1641
|
+
/** Stripe Checkout page. The user finishes it in a browser. */
|
|
1642
|
+
url: string;
|
|
1643
|
+
sessionId: string;
|
|
1644
|
+
/** Null when the account already had a trial: Pro starts at once and charges $19. */
|
|
1645
|
+
trialDays: number | null;
|
|
1646
|
+
trialCreditCents: number | null;
|
|
1647
|
+
}
|
|
1648
|
+
interface StartProNowResult {
|
|
1649
|
+
/**
|
|
1650
|
+
* `active`: charged $19, the first paid month started. `requires_action`: the bank
|
|
1651
|
+
* wants a confirmation (or declined); open `invoiceUrl`, the trial continues.
|
|
1652
|
+
* `failed`: nothing changed, the trial continues.
|
|
1653
|
+
*/
|
|
1654
|
+
status: 'active' | 'requires_action' | 'failed';
|
|
1655
|
+
invoiceUrl?: string | null;
|
|
1656
|
+
}
|
|
1657
|
+
interface PromoRedemption {
|
|
1658
|
+
/** `pending_payment_method`: held for the trial Checkout starts. `applied`: applied now. */
|
|
1659
|
+
status: string;
|
|
1660
|
+
code?: string;
|
|
1661
|
+
/** The trial credits (older servers: the credit amount). */
|
|
1662
|
+
creditCents: number;
|
|
1663
|
+
expiresAt: number | null;
|
|
1664
|
+
/** Kept for older clients. */
|
|
1665
|
+
balanceCents: number;
|
|
1666
|
+
/** Trial length the code gives. Missing from servers before Pro. */
|
|
1667
|
+
trialDays?: number;
|
|
1668
|
+
trialCreditCents?: number;
|
|
1669
|
+
/** `next_checkout`: held for the trial `startCheckout` opens. `current_trial`: extended the running trial. */
|
|
1670
|
+
appliesTo?: 'next_checkout' | 'current_trial';
|
|
1671
|
+
}
|
|
1672
|
+
/**
|
|
1673
|
+
* The account's plan, balance and usage.
|
|
1674
|
+
*
|
|
1675
|
+
* Pro costs $19/month, taxes included, with $19 of credits each month; usage above that
|
|
1676
|
+
* is pay as you go, invoiced as it builds up. A new account starts with a 7-day trial
|
|
1677
|
+
* with $5 of credits. Enterprise is pay as you go, invoiced monthly. Old prepaid
|
|
1678
|
+
* credits accounts (`plan: 'payg'`) keep {@link balance} and {@link transactions}
|
|
1679
|
+
* until 1 November 2026.
|
|
1562
1680
|
*
|
|
1563
1681
|
* Billing is **account-scoped, not workspace-scoped**: every workspace you create for
|
|
1564
1682
|
* a user bills to the account that owns the key. That is what makes per-user
|
|
1565
|
-
* workspaces a safe pattern — your users get isolation, you keep one bill
|
|
1566
|
-
* what makes {@link Balance.runwayHours} worth watching before you provision more.
|
|
1683
|
+
* workspaces a safe pattern — your users get isolation, you keep one bill.
|
|
1567
1684
|
*
|
|
1568
|
-
* **Requires an unscoped key
|
|
1569
|
-
*
|
|
1570
|
-
*
|
|
1571
|
-
*
|
|
1572
|
-
*
|
|
1685
|
+
* **Requires an unscoped key**, except {@link subscription} with a `workspaceId` the
|
|
1686
|
+
* key can reach. A scoped key is refused with 403 `ACCOUNT_SCOPE_REQUIRED`, because a
|
|
1687
|
+
* scoped key is meant to be handed to an end user, who should not be reading your
|
|
1688
|
+
* card details or changing your plan. For per-workspace spend, use
|
|
1689
|
+
* {@link MetricsAPI.cost} instead.
|
|
1690
|
+
*
|
|
1691
|
+
* Checkout and invoices are web pages: methods return their URL for the user to open.
|
|
1692
|
+
* Nothing here retries a payment.
|
|
1573
1693
|
*/
|
|
1574
1694
|
declare class BillingAPI {
|
|
1575
1695
|
private readonly client;
|
|
1576
1696
|
constructor(client: PlatformClient);
|
|
1577
|
-
/**
|
|
1697
|
+
/**
|
|
1698
|
+
* The plan: trial, this month's credits, overage, next charge, cancel date. With
|
|
1699
|
+
* `workspaceId`, the plan of that workspace's owner (`isOwner: false`, no card or
|
|
1700
|
+
* invoice fields).
|
|
1701
|
+
*/
|
|
1702
|
+
subscription(opts?: {
|
|
1703
|
+
workspaceId?: string;
|
|
1704
|
+
}): Promise<Subscription>;
|
|
1705
|
+
/**
|
|
1706
|
+
* Opens Stripe Checkout for Pro: the trial when the account can have one, otherwise
|
|
1707
|
+
* Pro at once ($19 today). Returns the page for the user to finish; a second call
|
|
1708
|
+
* while it is open returns the same session.
|
|
1709
|
+
*/
|
|
1710
|
+
startCheckout(opts?: StartCheckoutOpts): Promise<CheckoutSession>;
|
|
1711
|
+
/** Ends the trial now: charges $19 and starts the first paid month with $19 of credits. */
|
|
1712
|
+
startProNow(): Promise<StartProNowResult>;
|
|
1713
|
+
/** Cancels Pro at the end of the current month or trial. Cancelling in the trial costs nothing. */
|
|
1714
|
+
cancel(): Promise<{
|
|
1715
|
+
cancelAt: number | null;
|
|
1716
|
+
}>;
|
|
1717
|
+
/** Undoes {@link cancel}: Pro renews as usual. */
|
|
1718
|
+
resume(): Promise<{
|
|
1719
|
+
cancelAt: null;
|
|
1720
|
+
}>;
|
|
1721
|
+
/** Redeems a promo code: a longer trial with more trial credits. Works only before the first payment. */
|
|
1722
|
+
redeemPromo(code: string): Promise<PromoRedemption>;
|
|
1723
|
+
/** Prepaid credits balance, status, burn rate and runway (old `payg` accounts and enterprise). */
|
|
1578
1724
|
balance(): Promise<Balance>;
|
|
1579
|
-
/** A page of balance transactions, newest first. */
|
|
1725
|
+
/** A page of balance transactions, newest first (old `payg` accounts and enterprise). */
|
|
1580
1726
|
transactions(opts?: ListTransactionsOpts): Promise<TransactionPage>;
|
|
1581
1727
|
/** Cost summary for the current billing period, broken down by resource. */
|
|
1582
1728
|
summary(): Promise<unknown>;
|
|
1583
1729
|
/** Live (not-yet-invoiced) usage accumulating right now. */
|
|
1584
1730
|
live(): Promise<unknown>;
|
|
1731
|
+
/** Saved cards. Cards are added in Checkout or on the Billing page. */
|
|
1585
1732
|
paymentMethods(): Promise<{
|
|
1586
1733
|
items: unknown[];
|
|
1587
1734
|
}>;
|
|
1588
|
-
setupPaymentMethod(returnUrl?: string): Promise<{
|
|
1589
|
-
url: string;
|
|
1590
|
-
}>;
|
|
1591
1735
|
removePaymentMethod(id: string): Promise<void>;
|
|
1592
|
-
purchase(creditCents: number, opts?: {
|
|
1593
|
-
paymentMethod?: 'card' | 'crypto';
|
|
1594
|
-
returnUrl?: string;
|
|
1595
|
-
}): Promise<{
|
|
1596
|
-
url: string;
|
|
1597
|
-
sessionId?: string;
|
|
1598
|
-
}>;
|
|
1599
|
-
autoTopup(): Promise<unknown>;
|
|
1600
|
-
setAutoTopup(opts: {
|
|
1601
|
-
enabled: boolean;
|
|
1602
|
-
thresholdCents: number;
|
|
1603
|
-
amountCents: number;
|
|
1604
|
-
paymentMethodIds: string[];
|
|
1605
|
-
}): Promise<unknown>;
|
|
1606
|
-
runAutoTopup(): Promise<unknown>;
|
|
1607
|
-
redeemPromo(code: string): Promise<unknown>;
|
|
1608
|
-
x402Quote(creditCents: number): Promise<unknown>;
|
|
1609
|
-
paymentStatus(attemptId: string): Promise<unknown>;
|
|
1610
|
-
/** Pay with the CLI's durable x402 journal. Requires CLI >= 4.0.8. Amounts are cents. */
|
|
1611
|
-
payX402(creditCents: number, opts: {
|
|
1612
|
-
maxTotalCents: number;
|
|
1613
|
-
requestId?: string;
|
|
1614
|
-
executable?: string;
|
|
1615
|
-
}): Promise<unknown>;
|
|
1616
1736
|
}
|
|
1617
1737
|
|
|
1618
1738
|
interface VolumeInfo {
|
|
@@ -1896,6 +2016,34 @@ declare class ConflictError extends LizardError {
|
|
|
1896
2016
|
declare class TimeoutError extends LizardError {
|
|
1897
2017
|
constructor(message?: string);
|
|
1898
2018
|
}
|
|
2019
|
+
/**
|
|
2020
|
+
* The account has to pay before it can do this (HTTP 402). Every create call answers
|
|
2021
|
+
* 402 when the account has no plan yet, its trial credits are used up, or an invoice
|
|
2022
|
+
* is unpaid. Show {@link message} to the user as is and send them to {@link url}.
|
|
2023
|
+
*
|
|
2024
|
+
* Still a {@link LizardError}, so existing `catch` blocks keep working.
|
|
2025
|
+
*/
|
|
2026
|
+
declare class PaymentRequiredError extends LizardError {
|
|
2027
|
+
/**
|
|
2028
|
+
* Why payment is needed: `trial_available` (start the Pro trial),
|
|
2029
|
+
* `subscription_required` (the trial was used: start Pro), `trial_credits_used`
|
|
2030
|
+
* (start Pro now), `past_due` or `paused` (pay the open invoice), or, for accounts
|
|
2031
|
+
* on the old prepaid credits, `grace`, `frozen`, `card_required` or
|
|
2032
|
+
* `credits_required`. {@link LizardError.status} stays the HTTP status, 402.
|
|
2033
|
+
*/
|
|
2034
|
+
paymentStatus?: string;
|
|
2035
|
+
/** Billing page that starts the Pro trial, or Pro when the trial was used. */
|
|
2036
|
+
subscribeUrl?: string;
|
|
2037
|
+
/** The Billing page. */
|
|
2038
|
+
billingUrl?: string;
|
|
2039
|
+
/** The Credits page, for accounts on the old prepaid credits. */
|
|
2040
|
+
topupUrl?: string;
|
|
2041
|
+
/** Stripe page that pays an unpaid invoice (`code` `UNPAID_INVOICE`). */
|
|
2042
|
+
invoiceUrl?: string;
|
|
2043
|
+
constructor(message?: string);
|
|
2044
|
+
/** The one page to open next for this {@link paymentStatus}. */
|
|
2045
|
+
get url(): string | undefined;
|
|
2046
|
+
}
|
|
1899
2047
|
|
|
1900
2048
|
/** A single output item produced during code execution. */
|
|
1901
2049
|
type OutputItem = {
|
|
@@ -2070,4 +2218,4 @@ declare class LizardCLI {
|
|
|
2070
2218
|
}): Promise<CLIResult>;
|
|
2071
2219
|
}
|
|
2072
2220
|
|
|
2073
|
-
export { type Account, type Addon, type AddonType, AddonsAPI, type ApiKey, type ApiKeyScope, ApiKeysAPI, AuthenticationError, type Balance, BillingAPI, type CLIOptions, type CLIResult, type ClickOpts, type CodeContext, CodeSandbox, ConfigApplyError, type ConfigResult, ConflictError, type ConnectionOpts, type CostMetrics, type CreateAddonOpts, type CreateApiKeyOpts, type CreateContextOpts, type CreateProjectOpts, type CreateServiceOpts, type CreateVolumeOpts, type CreateWorkspaceOpts, type CreatedApiKey, type DeployEvent, DeployHandle, Desktop, type DesktopInfo, type DesktopStartOpts, type DomainInfo, type DomainStatus, DomainsAPI, Execution, ExecutionError, type ExposedPort, type FileInfo, type ForkResult, type FsEvent, type FsOpts, GitHubAPI, type ListTransactionsOpts, Lizard, LizardCLI, LizardError, type LizardOpts, type LogLine, type MetricPoint, type MetricRange, MetricsAPI, type MouseButton, NotFoundError, PlatformClient, type ProcessInfo, type ProcessOpts, type ProcessResult, type ProcessSignal, type Project, type ProjectConfig, type ProjectCost, ProjectsAPI, type RawMetrics, type Region, RegionsAPI, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, type SandboxSnapshot, type ScaleOpts, type ScrollDirection, type Secret, SecretsAPI, type Service, type ServiceMetrics, type ServiceUpdate, ServicesAPI, type SetSecretOpts, type SnapshotOpts, type SnapshotWaitOpts, StorageAPI, type StreamEvent, TimeoutError, type Transaction, type TransactionPage, Volume, type VolumeInfo, type Workspace, WorkspacesAPI, resolveProjectId };
|
|
2221
|
+
export { type Account, type Addon, type AddonType, AddonsAPI, type ApiKey, type ApiKeyScope, ApiKeysAPI, AuthenticationError, type Balance, BillingAPI, type CLIOptions, type CLIResult, type CheckoutSession, type ClickOpts, type CodeContext, CodeSandbox, ConfigApplyError, type ConfigResult, ConflictError, type ConnectionOpts, type CostMetrics, type CreateAddonOpts, type CreateApiKeyOpts, type CreateContextOpts, type CreateProjectOpts, type CreateServiceOpts, type CreateVolumeOpts, type CreateWorkspaceOpts, type CreatedApiKey, type DeployEvent, DeployHandle, Desktop, type DesktopInfo, type DesktopStartOpts, type DomainInfo, type DomainStatus, DomainsAPI, Execution, ExecutionError, type ExposedPort, type FileInfo, type ForkResult, type FsEvent, type FsOpts, GitHubAPI, type ListTransactionsOpts, Lizard, LizardCLI, LizardError, type LizardOpts, type LogLine, type MetricPoint, type MetricRange, MetricsAPI, type MouseButton, NotFoundError, PaymentRequiredError, type Plan, PlatformClient, type ProcessInfo, type ProcessOpts, type ProcessResult, type ProcessSignal, type Project, type ProjectConfig, type ProjectCost, ProjectsAPI, type PromoRedemption, type RawMetrics, type Region, RegionsAPI, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, type SandboxSnapshot, type ScaleOpts, type ScrollDirection, type Secret, SecretsAPI, type Service, type ServiceMetrics, type ServiceUpdate, ServicesAPI, type SetSecretOpts, type SnapshotOpts, type SnapshotWaitOpts, type StartCheckoutOpts, type StartProNowResult, StorageAPI, type StreamEvent, type Subscription, type SubscriptionStatus, TimeoutError, type Transaction, type TransactionPage, Volume, type VolumeInfo, type Workspace, WorkspacesAPI, resolveProjectId };
|
package/dist/index.d.ts
CHANGED
|
@@ -1520,6 +1520,7 @@ declare class RegionsAPI {
|
|
|
1520
1520
|
list(): Promise<Region[]>;
|
|
1521
1521
|
}
|
|
1522
1522
|
|
|
1523
|
+
/** Prepaid credits balance: old credits accounts (`plan: 'payg'`) until 1 November 2026, and enterprise usage. */
|
|
1523
1524
|
interface Balance {
|
|
1524
1525
|
plan: string;
|
|
1525
1526
|
status: 'active' | 'grace' | 'frozen' | string;
|
|
@@ -1558,61 +1559,180 @@ interface ListTransactionsOpts {
|
|
|
1558
1559
|
includeUsage?: boolean;
|
|
1559
1560
|
}
|
|
1560
1561
|
/**
|
|
1561
|
-
*
|
|
1562
|
+
* `none`: no plan yet (creating anything answers 402). `pro`: the Pro subscription, see
|
|
1563
|
+
* {@link Subscription.status}. `payg`: old prepaid credits, until 1 November 2026.
|
|
1564
|
+
* `enterprise`: pay as you go, invoiced monthly.
|
|
1565
|
+
*/
|
|
1566
|
+
type Plan = 'none' | 'pro' | 'payg' | 'enterprise';
|
|
1567
|
+
/** Pro subscription status; `none` when there is no subscription. */
|
|
1568
|
+
type SubscriptionStatus = 'trialing' | 'active' | 'past_due' | 'canceled' | 'none';
|
|
1569
|
+
interface Subscription {
|
|
1570
|
+
plan: Plan | (string & {});
|
|
1571
|
+
status: SubscriptionStatus | (string & {});
|
|
1572
|
+
/** False when read for a workspace the caller does not own; card and invoice fields are then null. */
|
|
1573
|
+
isOwner: boolean;
|
|
1574
|
+
/** 1900: $19/month. */
|
|
1575
|
+
priceCents: number;
|
|
1576
|
+
/** The price includes taxes. */
|
|
1577
|
+
taxIncluded: boolean;
|
|
1578
|
+
/** Credits included each paid month, in cents (1900). */
|
|
1579
|
+
includedCents: number;
|
|
1580
|
+
trial: {
|
|
1581
|
+
/** The account can start a trial now. */
|
|
1582
|
+
eligible: boolean;
|
|
1583
|
+
/** Trial length it would get, or got. */
|
|
1584
|
+
days: number | null;
|
|
1585
|
+
/** Trial credits, in cents. */
|
|
1586
|
+
creditCents: number | null;
|
|
1587
|
+
/** Promo code held for the trial, if any. */
|
|
1588
|
+
promoCode: string | null;
|
|
1589
|
+
/** Trial end (ms); null when not trialing. */
|
|
1590
|
+
endsAt: number | null;
|
|
1591
|
+
/** Trial credits used (trialing only). */
|
|
1592
|
+
usedCents: number | null;
|
|
1593
|
+
remainingCents: number | null;
|
|
1594
|
+
};
|
|
1595
|
+
/** The current Pro period; null when there is none. */
|
|
1596
|
+
period: {
|
|
1597
|
+
kind: 'trial' | 'paid';
|
|
1598
|
+
start: number;
|
|
1599
|
+
end: number;
|
|
1600
|
+
/** 500 in the trial, 1900 in a paid month. */
|
|
1601
|
+
includedCents: number;
|
|
1602
|
+
usedCents: number;
|
|
1603
|
+
/** Paid month: usage above the included credits. */
|
|
1604
|
+
overageCents: number;
|
|
1605
|
+
/** Of the overage, already invoiced. */
|
|
1606
|
+
billedOverageCents: number;
|
|
1607
|
+
unbilledOverageCents: number;
|
|
1608
|
+
/** Paid month: unbilled overage at which the next invoice goes out. */
|
|
1609
|
+
nextOverageChargeAtCents: number | null;
|
|
1610
|
+
} | null;
|
|
1611
|
+
/** Null when there is none, or the subscription is cancelling. */
|
|
1612
|
+
nextCharge: {
|
|
1613
|
+
at: number | null;
|
|
1614
|
+
amountCents: number;
|
|
1615
|
+
} | null;
|
|
1616
|
+
/** When a cancelled subscription ends (ms). */
|
|
1617
|
+
cancelAt: number | null;
|
|
1618
|
+
/** An invoice is unpaid. */
|
|
1619
|
+
pastDue: boolean;
|
|
1620
|
+
/** Stripe page that pays it (owner only). */
|
|
1621
|
+
openInvoiceUrl: string | null;
|
|
1622
|
+
paymentMethod: {
|
|
1623
|
+
brand: string;
|
|
1624
|
+
last4: string;
|
|
1625
|
+
expMonth: number;
|
|
1626
|
+
expYear: number;
|
|
1627
|
+
} | null;
|
|
1628
|
+
/** Pro only: `tier` is `trial` or `pro`. */
|
|
1629
|
+
limits: {
|
|
1630
|
+
tier: string;
|
|
1631
|
+
replicasPerApp: number;
|
|
1632
|
+
} | null;
|
|
1633
|
+
/** Pro Checkout is open for this account. */
|
|
1634
|
+
checkoutAvailable: boolean;
|
|
1635
|
+
}
|
|
1636
|
+
interface StartCheckoutOpts {
|
|
1637
|
+
/** Dashboard path to come back to after Checkout, e.g. `/projects/abc`. */
|
|
1638
|
+
returnUrl?: string;
|
|
1639
|
+
}
|
|
1640
|
+
interface CheckoutSession {
|
|
1641
|
+
/** Stripe Checkout page. The user finishes it in a browser. */
|
|
1642
|
+
url: string;
|
|
1643
|
+
sessionId: string;
|
|
1644
|
+
/** Null when the account already had a trial: Pro starts at once and charges $19. */
|
|
1645
|
+
trialDays: number | null;
|
|
1646
|
+
trialCreditCents: number | null;
|
|
1647
|
+
}
|
|
1648
|
+
interface StartProNowResult {
|
|
1649
|
+
/**
|
|
1650
|
+
* `active`: charged $19, the first paid month started. `requires_action`: the bank
|
|
1651
|
+
* wants a confirmation (or declined); open `invoiceUrl`, the trial continues.
|
|
1652
|
+
* `failed`: nothing changed, the trial continues.
|
|
1653
|
+
*/
|
|
1654
|
+
status: 'active' | 'requires_action' | 'failed';
|
|
1655
|
+
invoiceUrl?: string | null;
|
|
1656
|
+
}
|
|
1657
|
+
interface PromoRedemption {
|
|
1658
|
+
/** `pending_payment_method`: held for the trial Checkout starts. `applied`: applied now. */
|
|
1659
|
+
status: string;
|
|
1660
|
+
code?: string;
|
|
1661
|
+
/** The trial credits (older servers: the credit amount). */
|
|
1662
|
+
creditCents: number;
|
|
1663
|
+
expiresAt: number | null;
|
|
1664
|
+
/** Kept for older clients. */
|
|
1665
|
+
balanceCents: number;
|
|
1666
|
+
/** Trial length the code gives. Missing from servers before Pro. */
|
|
1667
|
+
trialDays?: number;
|
|
1668
|
+
trialCreditCents?: number;
|
|
1669
|
+
/** `next_checkout`: held for the trial `startCheckout` opens. `current_trial`: extended the running trial. */
|
|
1670
|
+
appliesTo?: 'next_checkout' | 'current_trial';
|
|
1671
|
+
}
|
|
1672
|
+
/**
|
|
1673
|
+
* The account's plan, balance and usage.
|
|
1674
|
+
*
|
|
1675
|
+
* Pro costs $19/month, taxes included, with $19 of credits each month; usage above that
|
|
1676
|
+
* is pay as you go, invoiced as it builds up. A new account starts with a 7-day trial
|
|
1677
|
+
* with $5 of credits. Enterprise is pay as you go, invoiced monthly. Old prepaid
|
|
1678
|
+
* credits accounts (`plan: 'payg'`) keep {@link balance} and {@link transactions}
|
|
1679
|
+
* until 1 November 2026.
|
|
1562
1680
|
*
|
|
1563
1681
|
* Billing is **account-scoped, not workspace-scoped**: every workspace you create for
|
|
1564
1682
|
* a user bills to the account that owns the key. That is what makes per-user
|
|
1565
|
-
* workspaces a safe pattern — your users get isolation, you keep one bill
|
|
1566
|
-
* what makes {@link Balance.runwayHours} worth watching before you provision more.
|
|
1683
|
+
* workspaces a safe pattern — your users get isolation, you keep one bill.
|
|
1567
1684
|
*
|
|
1568
|
-
* **Requires an unscoped key
|
|
1569
|
-
*
|
|
1570
|
-
*
|
|
1571
|
-
*
|
|
1572
|
-
*
|
|
1685
|
+
* **Requires an unscoped key**, except {@link subscription} with a `workspaceId` the
|
|
1686
|
+
* key can reach. A scoped key is refused with 403 `ACCOUNT_SCOPE_REQUIRED`, because a
|
|
1687
|
+
* scoped key is meant to be handed to an end user, who should not be reading your
|
|
1688
|
+
* card details or changing your plan. For per-workspace spend, use
|
|
1689
|
+
* {@link MetricsAPI.cost} instead.
|
|
1690
|
+
*
|
|
1691
|
+
* Checkout and invoices are web pages: methods return their URL for the user to open.
|
|
1692
|
+
* Nothing here retries a payment.
|
|
1573
1693
|
*/
|
|
1574
1694
|
declare class BillingAPI {
|
|
1575
1695
|
private readonly client;
|
|
1576
1696
|
constructor(client: PlatformClient);
|
|
1577
|
-
/**
|
|
1697
|
+
/**
|
|
1698
|
+
* The plan: trial, this month's credits, overage, next charge, cancel date. With
|
|
1699
|
+
* `workspaceId`, the plan of that workspace's owner (`isOwner: false`, no card or
|
|
1700
|
+
* invoice fields).
|
|
1701
|
+
*/
|
|
1702
|
+
subscription(opts?: {
|
|
1703
|
+
workspaceId?: string;
|
|
1704
|
+
}): Promise<Subscription>;
|
|
1705
|
+
/**
|
|
1706
|
+
* Opens Stripe Checkout for Pro: the trial when the account can have one, otherwise
|
|
1707
|
+
* Pro at once ($19 today). Returns the page for the user to finish; a second call
|
|
1708
|
+
* while it is open returns the same session.
|
|
1709
|
+
*/
|
|
1710
|
+
startCheckout(opts?: StartCheckoutOpts): Promise<CheckoutSession>;
|
|
1711
|
+
/** Ends the trial now: charges $19 and starts the first paid month with $19 of credits. */
|
|
1712
|
+
startProNow(): Promise<StartProNowResult>;
|
|
1713
|
+
/** Cancels Pro at the end of the current month or trial. Cancelling in the trial costs nothing. */
|
|
1714
|
+
cancel(): Promise<{
|
|
1715
|
+
cancelAt: number | null;
|
|
1716
|
+
}>;
|
|
1717
|
+
/** Undoes {@link cancel}: Pro renews as usual. */
|
|
1718
|
+
resume(): Promise<{
|
|
1719
|
+
cancelAt: null;
|
|
1720
|
+
}>;
|
|
1721
|
+
/** Redeems a promo code: a longer trial with more trial credits. Works only before the first payment. */
|
|
1722
|
+
redeemPromo(code: string): Promise<PromoRedemption>;
|
|
1723
|
+
/** Prepaid credits balance, status, burn rate and runway (old `payg` accounts and enterprise). */
|
|
1578
1724
|
balance(): Promise<Balance>;
|
|
1579
|
-
/** A page of balance transactions, newest first. */
|
|
1725
|
+
/** A page of balance transactions, newest first (old `payg` accounts and enterprise). */
|
|
1580
1726
|
transactions(opts?: ListTransactionsOpts): Promise<TransactionPage>;
|
|
1581
1727
|
/** Cost summary for the current billing period, broken down by resource. */
|
|
1582
1728
|
summary(): Promise<unknown>;
|
|
1583
1729
|
/** Live (not-yet-invoiced) usage accumulating right now. */
|
|
1584
1730
|
live(): Promise<unknown>;
|
|
1731
|
+
/** Saved cards. Cards are added in Checkout or on the Billing page. */
|
|
1585
1732
|
paymentMethods(): Promise<{
|
|
1586
1733
|
items: unknown[];
|
|
1587
1734
|
}>;
|
|
1588
|
-
setupPaymentMethod(returnUrl?: string): Promise<{
|
|
1589
|
-
url: string;
|
|
1590
|
-
}>;
|
|
1591
1735
|
removePaymentMethod(id: string): Promise<void>;
|
|
1592
|
-
purchase(creditCents: number, opts?: {
|
|
1593
|
-
paymentMethod?: 'card' | 'crypto';
|
|
1594
|
-
returnUrl?: string;
|
|
1595
|
-
}): Promise<{
|
|
1596
|
-
url: string;
|
|
1597
|
-
sessionId?: string;
|
|
1598
|
-
}>;
|
|
1599
|
-
autoTopup(): Promise<unknown>;
|
|
1600
|
-
setAutoTopup(opts: {
|
|
1601
|
-
enabled: boolean;
|
|
1602
|
-
thresholdCents: number;
|
|
1603
|
-
amountCents: number;
|
|
1604
|
-
paymentMethodIds: string[];
|
|
1605
|
-
}): Promise<unknown>;
|
|
1606
|
-
runAutoTopup(): Promise<unknown>;
|
|
1607
|
-
redeemPromo(code: string): Promise<unknown>;
|
|
1608
|
-
x402Quote(creditCents: number): Promise<unknown>;
|
|
1609
|
-
paymentStatus(attemptId: string): Promise<unknown>;
|
|
1610
|
-
/** Pay with the CLI's durable x402 journal. Requires CLI >= 4.0.8. Amounts are cents. */
|
|
1611
|
-
payX402(creditCents: number, opts: {
|
|
1612
|
-
maxTotalCents: number;
|
|
1613
|
-
requestId?: string;
|
|
1614
|
-
executable?: string;
|
|
1615
|
-
}): Promise<unknown>;
|
|
1616
1736
|
}
|
|
1617
1737
|
|
|
1618
1738
|
interface VolumeInfo {
|
|
@@ -1896,6 +2016,34 @@ declare class ConflictError extends LizardError {
|
|
|
1896
2016
|
declare class TimeoutError extends LizardError {
|
|
1897
2017
|
constructor(message?: string);
|
|
1898
2018
|
}
|
|
2019
|
+
/**
|
|
2020
|
+
* The account has to pay before it can do this (HTTP 402). Every create call answers
|
|
2021
|
+
* 402 when the account has no plan yet, its trial credits are used up, or an invoice
|
|
2022
|
+
* is unpaid. Show {@link message} to the user as is and send them to {@link url}.
|
|
2023
|
+
*
|
|
2024
|
+
* Still a {@link LizardError}, so existing `catch` blocks keep working.
|
|
2025
|
+
*/
|
|
2026
|
+
declare class PaymentRequiredError extends LizardError {
|
|
2027
|
+
/**
|
|
2028
|
+
* Why payment is needed: `trial_available` (start the Pro trial),
|
|
2029
|
+
* `subscription_required` (the trial was used: start Pro), `trial_credits_used`
|
|
2030
|
+
* (start Pro now), `past_due` or `paused` (pay the open invoice), or, for accounts
|
|
2031
|
+
* on the old prepaid credits, `grace`, `frozen`, `card_required` or
|
|
2032
|
+
* `credits_required`. {@link LizardError.status} stays the HTTP status, 402.
|
|
2033
|
+
*/
|
|
2034
|
+
paymentStatus?: string;
|
|
2035
|
+
/** Billing page that starts the Pro trial, or Pro when the trial was used. */
|
|
2036
|
+
subscribeUrl?: string;
|
|
2037
|
+
/** The Billing page. */
|
|
2038
|
+
billingUrl?: string;
|
|
2039
|
+
/** The Credits page, for accounts on the old prepaid credits. */
|
|
2040
|
+
topupUrl?: string;
|
|
2041
|
+
/** Stripe page that pays an unpaid invoice (`code` `UNPAID_INVOICE`). */
|
|
2042
|
+
invoiceUrl?: string;
|
|
2043
|
+
constructor(message?: string);
|
|
2044
|
+
/** The one page to open next for this {@link paymentStatus}. */
|
|
2045
|
+
get url(): string | undefined;
|
|
2046
|
+
}
|
|
1899
2047
|
|
|
1900
2048
|
/** A single output item produced during code execution. */
|
|
1901
2049
|
type OutputItem = {
|
|
@@ -2070,4 +2218,4 @@ declare class LizardCLI {
|
|
|
2070
2218
|
}): Promise<CLIResult>;
|
|
2071
2219
|
}
|
|
2072
2220
|
|
|
2073
|
-
export { type Account, type Addon, type AddonType, AddonsAPI, type ApiKey, type ApiKeyScope, ApiKeysAPI, AuthenticationError, type Balance, BillingAPI, type CLIOptions, type CLIResult, type ClickOpts, type CodeContext, CodeSandbox, ConfigApplyError, type ConfigResult, ConflictError, type ConnectionOpts, type CostMetrics, type CreateAddonOpts, type CreateApiKeyOpts, type CreateContextOpts, type CreateProjectOpts, type CreateServiceOpts, type CreateVolumeOpts, type CreateWorkspaceOpts, type CreatedApiKey, type DeployEvent, DeployHandle, Desktop, type DesktopInfo, type DesktopStartOpts, type DomainInfo, type DomainStatus, DomainsAPI, Execution, ExecutionError, type ExposedPort, type FileInfo, type ForkResult, type FsEvent, type FsOpts, GitHubAPI, type ListTransactionsOpts, Lizard, LizardCLI, LizardError, type LizardOpts, type LogLine, type MetricPoint, type MetricRange, MetricsAPI, type MouseButton, NotFoundError, PlatformClient, type ProcessInfo, type ProcessOpts, type ProcessResult, type ProcessSignal, type Project, type ProjectConfig, type ProjectCost, ProjectsAPI, type RawMetrics, type Region, RegionsAPI, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, type SandboxSnapshot, type ScaleOpts, type ScrollDirection, type Secret, SecretsAPI, type Service, type ServiceMetrics, type ServiceUpdate, ServicesAPI, type SetSecretOpts, type SnapshotOpts, type SnapshotWaitOpts, StorageAPI, type StreamEvent, TimeoutError, type Transaction, type TransactionPage, Volume, type VolumeInfo, type Workspace, WorkspacesAPI, resolveProjectId };
|
|
2221
|
+
export { type Account, type Addon, type AddonType, AddonsAPI, type ApiKey, type ApiKeyScope, ApiKeysAPI, AuthenticationError, type Balance, BillingAPI, type CLIOptions, type CLIResult, type CheckoutSession, type ClickOpts, type CodeContext, CodeSandbox, ConfigApplyError, type ConfigResult, ConflictError, type ConnectionOpts, type CostMetrics, type CreateAddonOpts, type CreateApiKeyOpts, type CreateContextOpts, type CreateProjectOpts, type CreateServiceOpts, type CreateVolumeOpts, type CreateWorkspaceOpts, type CreatedApiKey, type DeployEvent, DeployHandle, Desktop, type DesktopInfo, type DesktopStartOpts, type DomainInfo, type DomainStatus, DomainsAPI, Execution, ExecutionError, type ExposedPort, type FileInfo, type ForkResult, type FsEvent, type FsOpts, GitHubAPI, type ListTransactionsOpts, Lizard, LizardCLI, LizardError, type LizardOpts, type LogLine, type MetricPoint, type MetricRange, MetricsAPI, type MouseButton, NotFoundError, PaymentRequiredError, type Plan, PlatformClient, type ProcessInfo, type ProcessOpts, type ProcessResult, type ProcessSignal, type Project, type ProjectConfig, type ProjectCost, ProjectsAPI, type PromoRedemption, type RawMetrics, type Region, RegionsAPI, type RunCodeLanguage, type RunCodeOpts, Sandbox, type SandboxInfo, type SandboxOpts, type SandboxSnapshot, type ScaleOpts, type ScrollDirection, type Secret, SecretsAPI, type Service, type ServiceMetrics, type ServiceUpdate, ServicesAPI, type SetSecretOpts, type SnapshotOpts, type SnapshotWaitOpts, type StartCheckoutOpts, type StartProNowResult, StorageAPI, type StreamEvent, type Subscription, type SubscriptionStatus, TimeoutError, type Transaction, type TransactionPage, Volume, type VolumeInfo, type Workspace, WorkspacesAPI, resolveProjectId };
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(index_exports, {
|
|
|
36
36
|
LizardError: () => LizardError,
|
|
37
37
|
MetricsAPI: () => MetricsAPI,
|
|
38
38
|
NotFoundError: () => NotFoundError,
|
|
39
|
+
PaymentRequiredError: () => PaymentRequiredError,
|
|
39
40
|
PlatformClient: () => PlatformClient,
|
|
40
41
|
ProjectsAPI: () => ProjectsAPI,
|
|
41
42
|
RegionsAPI: () => RegionsAPI,
|
|
@@ -111,18 +112,44 @@ var TimeoutError = class extends LizardError {
|
|
|
111
112
|
this.name = "TimeoutError";
|
|
112
113
|
}
|
|
113
114
|
};
|
|
115
|
+
var PaymentRequiredError = class extends LizardError {
|
|
116
|
+
constructor(message = "Payment required") {
|
|
117
|
+
super(message);
|
|
118
|
+
this.name = "PaymentRequiredError";
|
|
119
|
+
}
|
|
120
|
+
/** The one page to open next for this {@link paymentStatus}. */
|
|
121
|
+
get url() {
|
|
122
|
+
const s = this.paymentStatus;
|
|
123
|
+
if (this.invoiceUrl) return this.invoiceUrl;
|
|
124
|
+
if ((s === "trial_available" || s === "subscription_required") && this.subscribeUrl) return this.subscribeUrl;
|
|
125
|
+
if (s && PREPAID_STATUSES.has(s) && this.topupUrl) return this.topupUrl;
|
|
126
|
+
return this.billingUrl ?? this.subscribeUrl ?? this.topupUrl;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
var PREPAID_STATUSES = /* @__PURE__ */ new Set(["grace", "frozen", "card_required", "credits_required"]);
|
|
130
|
+
var ERROR_CODE = /^[A-Z][A-Z0-9_]*$/;
|
|
114
131
|
async function handleApiError(res) {
|
|
115
|
-
let
|
|
116
|
-
let code;
|
|
132
|
+
let body = {};
|
|
117
133
|
try {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
if (typeof body.code === "string") code = body.code;
|
|
134
|
+
const parsed = await res.json();
|
|
135
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) body = parsed;
|
|
121
136
|
} catch {
|
|
122
|
-
message = res.statusText;
|
|
123
137
|
}
|
|
138
|
+
const text = (key) => typeof body[key] === "string" && body[key] ? body[key] : void 0;
|
|
139
|
+
const error = text("error");
|
|
140
|
+
const errorIsCode = !!error && ERROR_CODE.test(error);
|
|
141
|
+
const message = (errorIsCode ? text("message") ?? error : error ?? text("message")) ?? res.statusText;
|
|
142
|
+
const code = text("code") ?? (errorIsCode ? error : void 0);
|
|
124
143
|
let err;
|
|
125
|
-
if (res.status ===
|
|
144
|
+
if (res.status === 402) {
|
|
145
|
+
const paid = new PaymentRequiredError(message);
|
|
146
|
+
paid.paymentStatus = text("status");
|
|
147
|
+
paid.subscribeUrl = text("subscribeUrl");
|
|
148
|
+
paid.billingUrl = text("billingUrl");
|
|
149
|
+
paid.topupUrl = text("topupUrl");
|
|
150
|
+
paid.invoiceUrl = text("invoiceUrl");
|
|
151
|
+
err = paid;
|
|
152
|
+
} else if (res.status === 401 || res.status === 403) err = new AuthenticationError(message);
|
|
126
153
|
else if (res.status === 404) err = new NotFoundError(message);
|
|
127
154
|
else if (res.status === 409) err = new ConflictError(message);
|
|
128
155
|
else if (res.status === 408 || res.status === 504) err = new TimeoutError(message);
|
|
@@ -1672,88 +1699,54 @@ var RegionsAPI = class {
|
|
|
1672
1699
|
}
|
|
1673
1700
|
};
|
|
1674
1701
|
|
|
1675
|
-
// src/cli.ts
|
|
1676
|
-
var import_node_child_process = require("child_process");
|
|
1677
|
-
var LizardCLI = class {
|
|
1678
|
-
constructor(opts = {}) {
|
|
1679
|
-
this.opts = opts;
|
|
1680
|
-
}
|
|
1681
|
-
run(args, opts = {}) {
|
|
1682
|
-
return new Promise((resolve, reject) => {
|
|
1683
|
-
const env = { ...process.env };
|
|
1684
|
-
if (this.opts.apiKey) {
|
|
1685
|
-
env.LIZARD_API_KEY = this.opts.apiKey;
|
|
1686
|
-
env.LIZARD_TOKEN = this.opts.apiKey;
|
|
1687
|
-
}
|
|
1688
|
-
if (this.opts.apiUrl) env.LIZARD_API_URL = this.opts.apiUrl;
|
|
1689
|
-
const child = (0, import_node_child_process.spawn)(this.opts.executable ?? "lizard", ["--json", ...args], {
|
|
1690
|
-
cwd: this.opts.cwd,
|
|
1691
|
-
env,
|
|
1692
|
-
shell: false,
|
|
1693
|
-
stdio: "pipe",
|
|
1694
|
-
signal: opts.signal,
|
|
1695
|
-
timeout: this.opts.timeoutMs ?? 6e5
|
|
1696
|
-
});
|
|
1697
|
-
child.stdout.setEncoding("utf8");
|
|
1698
|
-
child.stderr.setEncoding("utf8");
|
|
1699
|
-
let stdout = "", stderr = "", bytes = 0;
|
|
1700
|
-
const collect = (stream, data) => {
|
|
1701
|
-
bytes += Buffer.byteLength(data);
|
|
1702
|
-
if (bytes > 16 * 1024 * 1024) {
|
|
1703
|
-
child.kill();
|
|
1704
|
-
reject(new Error("CLI output exceeds 16 MiB"));
|
|
1705
|
-
return;
|
|
1706
|
-
}
|
|
1707
|
-
if (stream === "stdout") stdout += data;
|
|
1708
|
-
else stderr += data;
|
|
1709
|
-
};
|
|
1710
|
-
child.stdout.on("data", (data) => collect("stdout", data));
|
|
1711
|
-
child.stderr.on("data", (data) => collect("stderr", data));
|
|
1712
|
-
child.on("error", reject);
|
|
1713
|
-
child.on("close", (code, signal) => {
|
|
1714
|
-
if (signal) {
|
|
1715
|
-
reject(new Error(`CLI ended with signal ${signal}`));
|
|
1716
|
-
return;
|
|
1717
|
-
}
|
|
1718
|
-
let events = [];
|
|
1719
|
-
try {
|
|
1720
|
-
events = [JSON.parse(stdout)];
|
|
1721
|
-
} catch {
|
|
1722
|
-
events = stdout.split("\n").filter(Boolean).flatMap((line) => {
|
|
1723
|
-
try {
|
|
1724
|
-
return [JSON.parse(line)];
|
|
1725
|
-
} catch {
|
|
1726
|
-
return [];
|
|
1727
|
-
}
|
|
1728
|
-
});
|
|
1729
|
-
}
|
|
1730
|
-
resolve({ code: code ?? 1, stdout, stderr, events });
|
|
1731
|
-
});
|
|
1732
|
-
child.stdin.on("error", (error) => {
|
|
1733
|
-
if (error.code !== "EPIPE") reject(error);
|
|
1734
|
-
});
|
|
1735
|
-
child.stdin.end(opts.stdin);
|
|
1736
|
-
});
|
|
1737
|
-
}
|
|
1738
|
-
};
|
|
1739
|
-
|
|
1740
1702
|
// src/platform/billing.ts
|
|
1741
1703
|
var BillingAPI = class {
|
|
1742
1704
|
constructor(client) {
|
|
1743
1705
|
this.client = client;
|
|
1744
1706
|
}
|
|
1745
|
-
/**
|
|
1707
|
+
/**
|
|
1708
|
+
* The plan: trial, this month's credits, overage, next charge, cancel date. With
|
|
1709
|
+
* `workspaceId`, the plan of that workspace's owner (`isOwner: false`, no card or
|
|
1710
|
+
* invoice fields).
|
|
1711
|
+
*/
|
|
1712
|
+
subscription(opts) {
|
|
1713
|
+
return this.client.get(query("/api/billing/subscription", { workspaceId: opts?.workspaceId }));
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Opens Stripe Checkout for Pro: the trial when the account can have one, otherwise
|
|
1717
|
+
* Pro at once ($19 today). Returns the page for the user to finish; a second call
|
|
1718
|
+
* while it is open returns the same session.
|
|
1719
|
+
*/
|
|
1720
|
+
startCheckout(opts = {}) {
|
|
1721
|
+
return this.client.post("/api/billing/subscription/checkout", { returnUrl: opts.returnUrl });
|
|
1722
|
+
}
|
|
1723
|
+
/** Ends the trial now: charges $19 and starts the first paid month with $19 of credits. */
|
|
1724
|
+
startProNow() {
|
|
1725
|
+
return this.client.post("/api/billing/subscription/start-now", {});
|
|
1726
|
+
}
|
|
1727
|
+
/** Cancels Pro at the end of the current month or trial. Cancelling in the trial costs nothing. */
|
|
1728
|
+
cancel() {
|
|
1729
|
+
return this.client.post("/api/billing/subscription/cancel", {});
|
|
1730
|
+
}
|
|
1731
|
+
/** Undoes {@link cancel}: Pro renews as usual. */
|
|
1732
|
+
resume() {
|
|
1733
|
+
return this.client.post("/api/billing/subscription/resume", {});
|
|
1734
|
+
}
|
|
1735
|
+
/** Redeems a promo code: a longer trial with more trial credits. Works only before the first payment. */
|
|
1736
|
+
redeemPromo(code) {
|
|
1737
|
+
return this.client.post("/api/billing/promo/redeem", { code });
|
|
1738
|
+
}
|
|
1739
|
+
/** Prepaid credits balance, status, burn rate and runway (old `payg` accounts and enterprise). */
|
|
1746
1740
|
balance() {
|
|
1747
1741
|
return this.client.get("/api/billing/balance");
|
|
1748
1742
|
}
|
|
1749
|
-
/** A page of balance transactions, newest first. */
|
|
1743
|
+
/** A page of balance transactions, newest first (old `payg` accounts and enterprise). */
|
|
1750
1744
|
transactions(opts) {
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
return this.client.get(`/api/billing/transactions${q ? `?${q}` : ""}`);
|
|
1745
|
+
return this.client.get(query("/api/billing/transactions", {
|
|
1746
|
+
limit: opts?.limit,
|
|
1747
|
+
cursor: opts?.cursor || void 0,
|
|
1748
|
+
includeUsage: opts?.includeUsage ? "1" : void 0
|
|
1749
|
+
}));
|
|
1757
1750
|
}
|
|
1758
1751
|
/** Cost summary for the current billing period, broken down by resource. */
|
|
1759
1752
|
summary() {
|
|
@@ -1763,46 +1756,13 @@ var BillingAPI = class {
|
|
|
1763
1756
|
live() {
|
|
1764
1757
|
return this.client.get("/api/billing/live");
|
|
1765
1758
|
}
|
|
1759
|
+
/** Saved cards. Cards are added in Checkout or on the Billing page. */
|
|
1766
1760
|
paymentMethods() {
|
|
1767
1761
|
return this.client.get("/api/billing/payment-methods");
|
|
1768
1762
|
}
|
|
1769
|
-
setupPaymentMethod(returnUrl) {
|
|
1770
|
-
return this.client.post("/api/billing/payment-methods/setup", { returnUrl });
|
|
1771
|
-
}
|
|
1772
1763
|
removePaymentMethod(id) {
|
|
1773
1764
|
return this.client.delete(`/api/billing/payment-methods/${encodeURIComponent(id)}`);
|
|
1774
1765
|
}
|
|
1775
|
-
purchase(creditCents, opts = {}) {
|
|
1776
|
-
if (!Number.isSafeInteger(creditCents) || creditCents <= 0) throw new Error("creditCents must be a positive integer");
|
|
1777
|
-
return this.client.post("/api/billing/purchase", { creditCents, paymentMethod: opts.paymentMethod ?? "card", returnUrl: opts.returnUrl });
|
|
1778
|
-
}
|
|
1779
|
-
autoTopup() {
|
|
1780
|
-
return this.client.get("/api/billing/auto-topup");
|
|
1781
|
-
}
|
|
1782
|
-
setAutoTopup(opts) {
|
|
1783
|
-
return this.client.put("/api/billing/auto-topup", opts);
|
|
1784
|
-
}
|
|
1785
|
-
runAutoTopup() {
|
|
1786
|
-
return this.client.post("/api/billing/auto-topup/run", {});
|
|
1787
|
-
}
|
|
1788
|
-
redeemPromo(code) {
|
|
1789
|
-
return this.client.post("/api/billing/promo/redeem", { code });
|
|
1790
|
-
}
|
|
1791
|
-
x402Quote(creditCents) {
|
|
1792
|
-
return this.client.post("/api/billing/purchase/x402/quote", { creditCents });
|
|
1793
|
-
}
|
|
1794
|
-
paymentStatus(attemptId) {
|
|
1795
|
-
return this.client.get(`/api/billing/purchase/x402/${encodeURIComponent(attemptId)}`);
|
|
1796
|
-
}
|
|
1797
|
-
/** Pay with the CLI's durable x402 journal. Requires CLI >= 4.0.8. Amounts are cents. */
|
|
1798
|
-
async payX402(creditCents, opts) {
|
|
1799
|
-
if (![creditCents, opts.maxTotalCents].every((n) => Number.isSafeInteger(n) && n > 0)) throw new Error("Payment amounts must be positive integer cents");
|
|
1800
|
-
const args = ["credits", "topup", (creditCents / 100).toFixed(2), "--method", "x402", "--max-total", (opts.maxTotalCents / 100).toFixed(2), "--yes"];
|
|
1801
|
-
if (opts.requestId) args.push("--request-id", opts.requestId);
|
|
1802
|
-
const result = await new LizardCLI({ apiKey: this.client.config.apiKey, apiUrl: this.client.config.apiUrl, executable: opts.executable }).run(args);
|
|
1803
|
-
if (result.code !== 0) throw new Error(`x402 CLI exited with code ${result.code}; inspect the payment journal or query paymentStatus before retrying`);
|
|
1804
|
-
return result.events[0];
|
|
1805
|
-
}
|
|
1806
1766
|
};
|
|
1807
1767
|
|
|
1808
1768
|
// src/volume/index.ts
|
|
@@ -2507,6 +2467,71 @@ function toBase64(text) {
|
|
|
2507
2467
|
for (let i = 0; i < bytes.length; i += 32768) s += String.fromCharCode(...bytes.subarray(i, i + 32768));
|
|
2508
2468
|
return btoa(s);
|
|
2509
2469
|
}
|
|
2470
|
+
|
|
2471
|
+
// src/cli.ts
|
|
2472
|
+
var import_node_child_process = require("child_process");
|
|
2473
|
+
var LizardCLI = class {
|
|
2474
|
+
constructor(opts = {}) {
|
|
2475
|
+
this.opts = opts;
|
|
2476
|
+
}
|
|
2477
|
+
run(args, opts = {}) {
|
|
2478
|
+
return new Promise((resolve, reject) => {
|
|
2479
|
+
const env = { ...process.env };
|
|
2480
|
+
if (this.opts.apiKey) {
|
|
2481
|
+
env.LIZARD_API_KEY = this.opts.apiKey;
|
|
2482
|
+
env.LIZARD_TOKEN = this.opts.apiKey;
|
|
2483
|
+
}
|
|
2484
|
+
if (this.opts.apiUrl) env.LIZARD_API_URL = this.opts.apiUrl;
|
|
2485
|
+
const child = (0, import_node_child_process.spawn)(this.opts.executable ?? "lizard", ["--json", ...args], {
|
|
2486
|
+
cwd: this.opts.cwd,
|
|
2487
|
+
env,
|
|
2488
|
+
shell: false,
|
|
2489
|
+
stdio: "pipe",
|
|
2490
|
+
signal: opts.signal,
|
|
2491
|
+
timeout: this.opts.timeoutMs ?? 6e5
|
|
2492
|
+
});
|
|
2493
|
+
child.stdout.setEncoding("utf8");
|
|
2494
|
+
child.stderr.setEncoding("utf8");
|
|
2495
|
+
let stdout = "", stderr = "", bytes = 0;
|
|
2496
|
+
const collect = (stream, data) => {
|
|
2497
|
+
bytes += Buffer.byteLength(data);
|
|
2498
|
+
if (bytes > 16 * 1024 * 1024) {
|
|
2499
|
+
child.kill();
|
|
2500
|
+
reject(new Error("CLI output exceeds 16 MiB"));
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
2503
|
+
if (stream === "stdout") stdout += data;
|
|
2504
|
+
else stderr += data;
|
|
2505
|
+
};
|
|
2506
|
+
child.stdout.on("data", (data) => collect("stdout", data));
|
|
2507
|
+
child.stderr.on("data", (data) => collect("stderr", data));
|
|
2508
|
+
child.on("error", reject);
|
|
2509
|
+
child.on("close", (code, signal) => {
|
|
2510
|
+
if (signal) {
|
|
2511
|
+
reject(new Error(`CLI ended with signal ${signal}`));
|
|
2512
|
+
return;
|
|
2513
|
+
}
|
|
2514
|
+
let events = [];
|
|
2515
|
+
try {
|
|
2516
|
+
events = [JSON.parse(stdout)];
|
|
2517
|
+
} catch {
|
|
2518
|
+
events = stdout.split("\n").filter(Boolean).flatMap((line) => {
|
|
2519
|
+
try {
|
|
2520
|
+
return [JSON.parse(line)];
|
|
2521
|
+
} catch {
|
|
2522
|
+
return [];
|
|
2523
|
+
}
|
|
2524
|
+
});
|
|
2525
|
+
}
|
|
2526
|
+
resolve({ code: code ?? 1, stdout, stderr, events });
|
|
2527
|
+
});
|
|
2528
|
+
child.stdin.on("error", (error) => {
|
|
2529
|
+
if (error.code !== "EPIPE") reject(error);
|
|
2530
|
+
});
|
|
2531
|
+
child.stdin.end(opts.stdin);
|
|
2532
|
+
});
|
|
2533
|
+
}
|
|
2534
|
+
};
|
|
2510
2535
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2511
2536
|
0 && (module.exports = {
|
|
2512
2537
|
AddonsAPI,
|
|
@@ -2525,6 +2550,7 @@ function toBase64(text) {
|
|
|
2525
2550
|
LizardError,
|
|
2526
2551
|
MetricsAPI,
|
|
2527
2552
|
NotFoundError,
|
|
2553
|
+
PaymentRequiredError,
|
|
2528
2554
|
PlatformClient,
|
|
2529
2555
|
ProjectsAPI,
|
|
2530
2556
|
RegionsAPI,
|
package/dist/index.mjs
CHANGED
|
@@ -59,18 +59,44 @@ var TimeoutError = class extends LizardError {
|
|
|
59
59
|
this.name = "TimeoutError";
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
|
+
var PaymentRequiredError = class extends LizardError {
|
|
63
|
+
constructor(message = "Payment required") {
|
|
64
|
+
super(message);
|
|
65
|
+
this.name = "PaymentRequiredError";
|
|
66
|
+
}
|
|
67
|
+
/** The one page to open next for this {@link paymentStatus}. */
|
|
68
|
+
get url() {
|
|
69
|
+
const s = this.paymentStatus;
|
|
70
|
+
if (this.invoiceUrl) return this.invoiceUrl;
|
|
71
|
+
if ((s === "trial_available" || s === "subscription_required") && this.subscribeUrl) return this.subscribeUrl;
|
|
72
|
+
if (s && PREPAID_STATUSES.has(s) && this.topupUrl) return this.topupUrl;
|
|
73
|
+
return this.billingUrl ?? this.subscribeUrl ?? this.topupUrl;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var PREPAID_STATUSES = /* @__PURE__ */ new Set(["grace", "frozen", "card_required", "credits_required"]);
|
|
77
|
+
var ERROR_CODE = /^[A-Z][A-Z0-9_]*$/;
|
|
62
78
|
async function handleApiError(res) {
|
|
63
|
-
let
|
|
64
|
-
let code;
|
|
79
|
+
let body = {};
|
|
65
80
|
try {
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
if (typeof body.code === "string") code = body.code;
|
|
81
|
+
const parsed = await res.json();
|
|
82
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) body = parsed;
|
|
69
83
|
} catch {
|
|
70
|
-
message = res.statusText;
|
|
71
84
|
}
|
|
85
|
+
const text = (key) => typeof body[key] === "string" && body[key] ? body[key] : void 0;
|
|
86
|
+
const error = text("error");
|
|
87
|
+
const errorIsCode = !!error && ERROR_CODE.test(error);
|
|
88
|
+
const message = (errorIsCode ? text("message") ?? error : error ?? text("message")) ?? res.statusText;
|
|
89
|
+
const code = text("code") ?? (errorIsCode ? error : void 0);
|
|
72
90
|
let err;
|
|
73
|
-
if (res.status ===
|
|
91
|
+
if (res.status === 402) {
|
|
92
|
+
const paid = new PaymentRequiredError(message);
|
|
93
|
+
paid.paymentStatus = text("status");
|
|
94
|
+
paid.subscribeUrl = text("subscribeUrl");
|
|
95
|
+
paid.billingUrl = text("billingUrl");
|
|
96
|
+
paid.topupUrl = text("topupUrl");
|
|
97
|
+
paid.invoiceUrl = text("invoiceUrl");
|
|
98
|
+
err = paid;
|
|
99
|
+
} else if (res.status === 401 || res.status === 403) err = new AuthenticationError(message);
|
|
74
100
|
else if (res.status === 404) err = new NotFoundError(message);
|
|
75
101
|
else if (res.status === 409) err = new ConflictError(message);
|
|
76
102
|
else if (res.status === 408 || res.status === 504) err = new TimeoutError(message);
|
|
@@ -1620,88 +1646,54 @@ var RegionsAPI = class {
|
|
|
1620
1646
|
}
|
|
1621
1647
|
};
|
|
1622
1648
|
|
|
1623
|
-
// src/cli.ts
|
|
1624
|
-
import { spawn } from "child_process";
|
|
1625
|
-
var LizardCLI = class {
|
|
1626
|
-
constructor(opts = {}) {
|
|
1627
|
-
this.opts = opts;
|
|
1628
|
-
}
|
|
1629
|
-
run(args, opts = {}) {
|
|
1630
|
-
return new Promise((resolve, reject) => {
|
|
1631
|
-
const env = { ...process.env };
|
|
1632
|
-
if (this.opts.apiKey) {
|
|
1633
|
-
env.LIZARD_API_KEY = this.opts.apiKey;
|
|
1634
|
-
env.LIZARD_TOKEN = this.opts.apiKey;
|
|
1635
|
-
}
|
|
1636
|
-
if (this.opts.apiUrl) env.LIZARD_API_URL = this.opts.apiUrl;
|
|
1637
|
-
const child = spawn(this.opts.executable ?? "lizard", ["--json", ...args], {
|
|
1638
|
-
cwd: this.opts.cwd,
|
|
1639
|
-
env,
|
|
1640
|
-
shell: false,
|
|
1641
|
-
stdio: "pipe",
|
|
1642
|
-
signal: opts.signal,
|
|
1643
|
-
timeout: this.opts.timeoutMs ?? 6e5
|
|
1644
|
-
});
|
|
1645
|
-
child.stdout.setEncoding("utf8");
|
|
1646
|
-
child.stderr.setEncoding("utf8");
|
|
1647
|
-
let stdout = "", stderr = "", bytes = 0;
|
|
1648
|
-
const collect = (stream, data) => {
|
|
1649
|
-
bytes += Buffer.byteLength(data);
|
|
1650
|
-
if (bytes > 16 * 1024 * 1024) {
|
|
1651
|
-
child.kill();
|
|
1652
|
-
reject(new Error("CLI output exceeds 16 MiB"));
|
|
1653
|
-
return;
|
|
1654
|
-
}
|
|
1655
|
-
if (stream === "stdout") stdout += data;
|
|
1656
|
-
else stderr += data;
|
|
1657
|
-
};
|
|
1658
|
-
child.stdout.on("data", (data) => collect("stdout", data));
|
|
1659
|
-
child.stderr.on("data", (data) => collect("stderr", data));
|
|
1660
|
-
child.on("error", reject);
|
|
1661
|
-
child.on("close", (code, signal) => {
|
|
1662
|
-
if (signal) {
|
|
1663
|
-
reject(new Error(`CLI ended with signal ${signal}`));
|
|
1664
|
-
return;
|
|
1665
|
-
}
|
|
1666
|
-
let events = [];
|
|
1667
|
-
try {
|
|
1668
|
-
events = [JSON.parse(stdout)];
|
|
1669
|
-
} catch {
|
|
1670
|
-
events = stdout.split("\n").filter(Boolean).flatMap((line) => {
|
|
1671
|
-
try {
|
|
1672
|
-
return [JSON.parse(line)];
|
|
1673
|
-
} catch {
|
|
1674
|
-
return [];
|
|
1675
|
-
}
|
|
1676
|
-
});
|
|
1677
|
-
}
|
|
1678
|
-
resolve({ code: code ?? 1, stdout, stderr, events });
|
|
1679
|
-
});
|
|
1680
|
-
child.stdin.on("error", (error) => {
|
|
1681
|
-
if (error.code !== "EPIPE") reject(error);
|
|
1682
|
-
});
|
|
1683
|
-
child.stdin.end(opts.stdin);
|
|
1684
|
-
});
|
|
1685
|
-
}
|
|
1686
|
-
};
|
|
1687
|
-
|
|
1688
1649
|
// src/platform/billing.ts
|
|
1689
1650
|
var BillingAPI = class {
|
|
1690
1651
|
constructor(client) {
|
|
1691
1652
|
this.client = client;
|
|
1692
1653
|
}
|
|
1693
|
-
/**
|
|
1654
|
+
/**
|
|
1655
|
+
* The plan: trial, this month's credits, overage, next charge, cancel date. With
|
|
1656
|
+
* `workspaceId`, the plan of that workspace's owner (`isOwner: false`, no card or
|
|
1657
|
+
* invoice fields).
|
|
1658
|
+
*/
|
|
1659
|
+
subscription(opts) {
|
|
1660
|
+
return this.client.get(query("/api/billing/subscription", { workspaceId: opts?.workspaceId }));
|
|
1661
|
+
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Opens Stripe Checkout for Pro: the trial when the account can have one, otherwise
|
|
1664
|
+
* Pro at once ($19 today). Returns the page for the user to finish; a second call
|
|
1665
|
+
* while it is open returns the same session.
|
|
1666
|
+
*/
|
|
1667
|
+
startCheckout(opts = {}) {
|
|
1668
|
+
return this.client.post("/api/billing/subscription/checkout", { returnUrl: opts.returnUrl });
|
|
1669
|
+
}
|
|
1670
|
+
/** Ends the trial now: charges $19 and starts the first paid month with $19 of credits. */
|
|
1671
|
+
startProNow() {
|
|
1672
|
+
return this.client.post("/api/billing/subscription/start-now", {});
|
|
1673
|
+
}
|
|
1674
|
+
/** Cancels Pro at the end of the current month or trial. Cancelling in the trial costs nothing. */
|
|
1675
|
+
cancel() {
|
|
1676
|
+
return this.client.post("/api/billing/subscription/cancel", {});
|
|
1677
|
+
}
|
|
1678
|
+
/** Undoes {@link cancel}: Pro renews as usual. */
|
|
1679
|
+
resume() {
|
|
1680
|
+
return this.client.post("/api/billing/subscription/resume", {});
|
|
1681
|
+
}
|
|
1682
|
+
/** Redeems a promo code: a longer trial with more trial credits. Works only before the first payment. */
|
|
1683
|
+
redeemPromo(code) {
|
|
1684
|
+
return this.client.post("/api/billing/promo/redeem", { code });
|
|
1685
|
+
}
|
|
1686
|
+
/** Prepaid credits balance, status, burn rate and runway (old `payg` accounts and enterprise). */
|
|
1694
1687
|
balance() {
|
|
1695
1688
|
return this.client.get("/api/billing/balance");
|
|
1696
1689
|
}
|
|
1697
|
-
/** A page of balance transactions, newest first. */
|
|
1690
|
+
/** A page of balance transactions, newest first (old `payg` accounts and enterprise). */
|
|
1698
1691
|
transactions(opts) {
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
return this.client.get(`/api/billing/transactions${q ? `?${q}` : ""}`);
|
|
1692
|
+
return this.client.get(query("/api/billing/transactions", {
|
|
1693
|
+
limit: opts?.limit,
|
|
1694
|
+
cursor: opts?.cursor || void 0,
|
|
1695
|
+
includeUsage: opts?.includeUsage ? "1" : void 0
|
|
1696
|
+
}));
|
|
1705
1697
|
}
|
|
1706
1698
|
/** Cost summary for the current billing period, broken down by resource. */
|
|
1707
1699
|
summary() {
|
|
@@ -1711,46 +1703,13 @@ var BillingAPI = class {
|
|
|
1711
1703
|
live() {
|
|
1712
1704
|
return this.client.get("/api/billing/live");
|
|
1713
1705
|
}
|
|
1706
|
+
/** Saved cards. Cards are added in Checkout or on the Billing page. */
|
|
1714
1707
|
paymentMethods() {
|
|
1715
1708
|
return this.client.get("/api/billing/payment-methods");
|
|
1716
1709
|
}
|
|
1717
|
-
setupPaymentMethod(returnUrl) {
|
|
1718
|
-
return this.client.post("/api/billing/payment-methods/setup", { returnUrl });
|
|
1719
|
-
}
|
|
1720
1710
|
removePaymentMethod(id) {
|
|
1721
1711
|
return this.client.delete(`/api/billing/payment-methods/${encodeURIComponent(id)}`);
|
|
1722
1712
|
}
|
|
1723
|
-
purchase(creditCents, opts = {}) {
|
|
1724
|
-
if (!Number.isSafeInteger(creditCents) || creditCents <= 0) throw new Error("creditCents must be a positive integer");
|
|
1725
|
-
return this.client.post("/api/billing/purchase", { creditCents, paymentMethod: opts.paymentMethod ?? "card", returnUrl: opts.returnUrl });
|
|
1726
|
-
}
|
|
1727
|
-
autoTopup() {
|
|
1728
|
-
return this.client.get("/api/billing/auto-topup");
|
|
1729
|
-
}
|
|
1730
|
-
setAutoTopup(opts) {
|
|
1731
|
-
return this.client.put("/api/billing/auto-topup", opts);
|
|
1732
|
-
}
|
|
1733
|
-
runAutoTopup() {
|
|
1734
|
-
return this.client.post("/api/billing/auto-topup/run", {});
|
|
1735
|
-
}
|
|
1736
|
-
redeemPromo(code) {
|
|
1737
|
-
return this.client.post("/api/billing/promo/redeem", { code });
|
|
1738
|
-
}
|
|
1739
|
-
x402Quote(creditCents) {
|
|
1740
|
-
return this.client.post("/api/billing/purchase/x402/quote", { creditCents });
|
|
1741
|
-
}
|
|
1742
|
-
paymentStatus(attemptId) {
|
|
1743
|
-
return this.client.get(`/api/billing/purchase/x402/${encodeURIComponent(attemptId)}`);
|
|
1744
|
-
}
|
|
1745
|
-
/** Pay with the CLI's durable x402 journal. Requires CLI >= 4.0.8. Amounts are cents. */
|
|
1746
|
-
async payX402(creditCents, opts) {
|
|
1747
|
-
if (![creditCents, opts.maxTotalCents].every((n) => Number.isSafeInteger(n) && n > 0)) throw new Error("Payment amounts must be positive integer cents");
|
|
1748
|
-
const args = ["credits", "topup", (creditCents / 100).toFixed(2), "--method", "x402", "--max-total", (opts.maxTotalCents / 100).toFixed(2), "--yes"];
|
|
1749
|
-
if (opts.requestId) args.push("--request-id", opts.requestId);
|
|
1750
|
-
const result = await new LizardCLI({ apiKey: this.client.config.apiKey, apiUrl: this.client.config.apiUrl, executable: opts.executable }).run(args);
|
|
1751
|
-
if (result.code !== 0) throw new Error(`x402 CLI exited with code ${result.code}; inspect the payment journal or query paymentStatus before retrying`);
|
|
1752
|
-
return result.events[0];
|
|
1753
|
-
}
|
|
1754
1713
|
};
|
|
1755
1714
|
|
|
1756
1715
|
// src/volume/index.ts
|
|
@@ -2455,6 +2414,71 @@ function toBase64(text) {
|
|
|
2455
2414
|
for (let i = 0; i < bytes.length; i += 32768) s += String.fromCharCode(...bytes.subarray(i, i + 32768));
|
|
2456
2415
|
return btoa(s);
|
|
2457
2416
|
}
|
|
2417
|
+
|
|
2418
|
+
// src/cli.ts
|
|
2419
|
+
import { spawn } from "child_process";
|
|
2420
|
+
var LizardCLI = class {
|
|
2421
|
+
constructor(opts = {}) {
|
|
2422
|
+
this.opts = opts;
|
|
2423
|
+
}
|
|
2424
|
+
run(args, opts = {}) {
|
|
2425
|
+
return new Promise((resolve, reject) => {
|
|
2426
|
+
const env = { ...process.env };
|
|
2427
|
+
if (this.opts.apiKey) {
|
|
2428
|
+
env.LIZARD_API_KEY = this.opts.apiKey;
|
|
2429
|
+
env.LIZARD_TOKEN = this.opts.apiKey;
|
|
2430
|
+
}
|
|
2431
|
+
if (this.opts.apiUrl) env.LIZARD_API_URL = this.opts.apiUrl;
|
|
2432
|
+
const child = spawn(this.opts.executable ?? "lizard", ["--json", ...args], {
|
|
2433
|
+
cwd: this.opts.cwd,
|
|
2434
|
+
env,
|
|
2435
|
+
shell: false,
|
|
2436
|
+
stdio: "pipe",
|
|
2437
|
+
signal: opts.signal,
|
|
2438
|
+
timeout: this.opts.timeoutMs ?? 6e5
|
|
2439
|
+
});
|
|
2440
|
+
child.stdout.setEncoding("utf8");
|
|
2441
|
+
child.stderr.setEncoding("utf8");
|
|
2442
|
+
let stdout = "", stderr = "", bytes = 0;
|
|
2443
|
+
const collect = (stream, data) => {
|
|
2444
|
+
bytes += Buffer.byteLength(data);
|
|
2445
|
+
if (bytes > 16 * 1024 * 1024) {
|
|
2446
|
+
child.kill();
|
|
2447
|
+
reject(new Error("CLI output exceeds 16 MiB"));
|
|
2448
|
+
return;
|
|
2449
|
+
}
|
|
2450
|
+
if (stream === "stdout") stdout += data;
|
|
2451
|
+
else stderr += data;
|
|
2452
|
+
};
|
|
2453
|
+
child.stdout.on("data", (data) => collect("stdout", data));
|
|
2454
|
+
child.stderr.on("data", (data) => collect("stderr", data));
|
|
2455
|
+
child.on("error", reject);
|
|
2456
|
+
child.on("close", (code, signal) => {
|
|
2457
|
+
if (signal) {
|
|
2458
|
+
reject(new Error(`CLI ended with signal ${signal}`));
|
|
2459
|
+
return;
|
|
2460
|
+
}
|
|
2461
|
+
let events = [];
|
|
2462
|
+
try {
|
|
2463
|
+
events = [JSON.parse(stdout)];
|
|
2464
|
+
} catch {
|
|
2465
|
+
events = stdout.split("\n").filter(Boolean).flatMap((line) => {
|
|
2466
|
+
try {
|
|
2467
|
+
return [JSON.parse(line)];
|
|
2468
|
+
} catch {
|
|
2469
|
+
return [];
|
|
2470
|
+
}
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
resolve({ code: code ?? 1, stdout, stderr, events });
|
|
2474
|
+
});
|
|
2475
|
+
child.stdin.on("error", (error) => {
|
|
2476
|
+
if (error.code !== "EPIPE") reject(error);
|
|
2477
|
+
});
|
|
2478
|
+
child.stdin.end(opts.stdin);
|
|
2479
|
+
});
|
|
2480
|
+
}
|
|
2481
|
+
};
|
|
2458
2482
|
export {
|
|
2459
2483
|
AddonsAPI,
|
|
2460
2484
|
ApiKeysAPI,
|
|
@@ -2472,6 +2496,7 @@ export {
|
|
|
2472
2496
|
LizardError,
|
|
2473
2497
|
MetricsAPI,
|
|
2474
2498
|
NotFoundError,
|
|
2499
|
+
PaymentRequiredError,
|
|
2475
2500
|
PlatformClient,
|
|
2476
2501
|
ProjectsAPI,
|
|
2477
2502
|
RegionsAPI,
|
package/package.json
CHANGED