@letterstory/cli 0.148.4 → 0.149.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/lib/cli.mjs +3 -1
- package/lib/commands/admin.mjs +57 -2
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
|
|
67
67
|
// Matches cli/package.json; publish-cli.yml rewrites both to the published version.
|
|
68
68
|
// Matches cli/package.json; publish-cli.yml rewrites both to the published version.
|
|
69
|
-
export const VERSION = "0.
|
|
69
|
+
export const VERSION = "0.149.0";
|
|
70
70
|
|
|
71
71
|
// Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
|
|
72
72
|
// can't accidentally swallow the id as --json's value. Every `type: "bool"` flag (and its
|
|
@@ -971,6 +971,8 @@ Admin (STAFF key — --staff-key / LETTERSTORY_STAFF_API_KEY; acts before an org
|
|
|
971
971
|
| payments [--org <org-id>] [--open] | payments retry <lago-invoice-id> | payments run [--dry]
|
|
972
972
|
| signups [--status open|card_saved|provisioned|paid|abandoned]
|
|
973
973
|
| cap <org-id> <dollars|off> [--why "…"] | cancel <org-id> --why "…" --yes
|
|
974
|
+
| move <org-id> --plan starter|growth|scale [--ratio N [--why "…"]] [--reason "…"] [--stripe-subscription sub_…] [--dry]
|
|
975
|
+
| changes [--org <org-id>] | changes cancel <org-id>
|
|
974
976
|
Usage billing on Lago: the plan catalog, an org's
|
|
975
977
|
plan and gifted ratio, Lago's tokens against ours,
|
|
976
978
|
forwarding usage now, failed payments and the
|
package/lib/commands/admin.mjs
CHANGED
|
@@ -5215,7 +5215,11 @@ const LAGO_USAGE = `Usage: admin billing lago <command>
|
|
|
5215
5215
|
payments run [--dry] one pass of the failed-payment loop now (--dry: report only)
|
|
5216
5216
|
signups [--status open|card_saved|provisioned|paid|abandoned] new paying orgs on their way onto Lago
|
|
5217
5217
|
cap <org-id> <dollars|off> [--why "…"] set an account's monthly spend cap on overage (off: no cap)
|
|
5218
|
-
cancel <org-id> --why "…" --yes end an account's Lago plan now and refund its first invoice
|
|
5218
|
+
cancel <org-id> --why "…" --yes end an account's Lago plan now and refund its first invoice
|
|
5219
|
+
move <org-id> --plan starter [--ratio 4] [--why "…" above 4x] [--reason "…"] [--complimentary 20000] [--review 2027-05-01] [--stripe-subscription sub_…] [--dry]
|
|
5220
|
+
move an existing customer from Stripe to Lago at their renewal
|
|
5221
|
+
changes [--org <org-id>] term changes waiting to take effect (moves, cheaper plans, new ratios)
|
|
5222
|
+
changes cancel <org-id> take back an org's scheduled change before it takes effect`;
|
|
5219
5223
|
|
|
5220
5224
|
/** admin billing lago … — staff operations on Lago (docs/billing/lago-integration.md). */
|
|
5221
5225
|
async function cmdAdminBilling(ctx) {
|
|
@@ -5259,7 +5263,9 @@ async function cmdAdminBilling(ctx) {
|
|
|
5259
5263
|
);
|
|
5260
5264
|
ok(
|
|
5261
5265
|
ctx,
|
|
5262
|
-
|
|
5266
|
+
result.action === "scheduled"
|
|
5267
|
+
? `Scheduled: from ${result.effectiveAt}, ${result.includedTokens} tokens included, overage $${result.overageUsdPerToken} a token (Lago bills today's terms until then).`
|
|
5268
|
+
: `${result.action === "created" ? "On Lago" : "Already on Lago"}: ${result.subscriptionId}, ${result.includedTokens} tokens included, overage $${result.overageUsdPerToken} a token, from ${result.startsAt}.`
|
|
5263
5269
|
);
|
|
5264
5270
|
printResult(io, flags, result);
|
|
5265
5271
|
return 0;
|
|
@@ -5360,6 +5366,55 @@ async function cmdAdminBilling(ctx) {
|
|
|
5360
5366
|
);
|
|
5361
5367
|
return 0;
|
|
5362
5368
|
}
|
|
5369
|
+
case "move": {
|
|
5370
|
+
const orgId = requirePositional(positionals, 2, "org-id");
|
|
5371
|
+
const plan = flagStr(flags.plan);
|
|
5372
|
+
if (!plan) throw new CliError(LAGO_USAGE);
|
|
5373
|
+
const result = await staffPost(
|
|
5374
|
+
ctx,
|
|
5375
|
+
`${LAGO}/move`,
|
|
5376
|
+
compact({
|
|
5377
|
+
orgId,
|
|
5378
|
+
planCode: plan,
|
|
5379
|
+
ratio: flagNum(flags.ratio),
|
|
5380
|
+
exceptionReason: flagStr(flags.why),
|
|
5381
|
+
reason: flagStr(flags.reason),
|
|
5382
|
+
complimentaryTokens: flagNum(flags.complimentary),
|
|
5383
|
+
reviewAt: flagStr(flags.review),
|
|
5384
|
+
stripeSubscriptionId: flagStr(flags["stripe-subscription"]),
|
|
5385
|
+
dryRun: flags.dry ? true : undefined,
|
|
5386
|
+
})
|
|
5387
|
+
);
|
|
5388
|
+
const p = result.plan;
|
|
5389
|
+
ok(
|
|
5390
|
+
ctx,
|
|
5391
|
+
`${result.dryRun ? "Would move" : "Moving"} ${p.orgId} from Stripe ${p.from.stripeSubscriptionId} (${p.from.product ?? "subscription"}) to Lago ${p.to.plan} at its renewal ${p.from.renewsAt}: Stripe stops then, Lago charges $${(p.to.amountCents / 100).toFixed(2)} then (${p.to.includedTokens} tokens included, overage $${p.to.overageUsdPerToken} a token).`
|
|
5392
|
+
);
|
|
5393
|
+
printResult(io, flags, result);
|
|
5394
|
+
return 0;
|
|
5395
|
+
}
|
|
5396
|
+
case "changes": {
|
|
5397
|
+
if (positionals[2] === "cancel") {
|
|
5398
|
+
const orgId = requirePositional(positionals, 3, "org-id");
|
|
5399
|
+
const result = await staffRequest(ctx, "DELETE", `${LAGO}/changes`, { orgId });
|
|
5400
|
+
ok(ctx, `Taken back: the ${result.canceled.kind} scheduled for ${result.canceled.effective_at}.`);
|
|
5401
|
+
printResult(io, flags, result);
|
|
5402
|
+
return 0;
|
|
5403
|
+
}
|
|
5404
|
+
const params = new URLSearchParams(compact({ orgId: flagStr(flags.org) }));
|
|
5405
|
+
const result = await staffRequest(ctx, "GET", `${LAGO}/changes${params.size ? `?${params}` : ""}`);
|
|
5406
|
+
printResult(io, flags, result, (r) =>
|
|
5407
|
+
r.changes.length
|
|
5408
|
+
? r.changes
|
|
5409
|
+
.map(
|
|
5410
|
+
(c) =>
|
|
5411
|
+
`${c.effective_at} ${c.kind.padEnd(9)} ${c.organizations?.name ?? c.org_id} → ${c.plan_code} ${c.ratio}x (by ${c.requested_by}${c.last_error ? `; waiting: ${c.last_error}` : ""})`
|
|
5412
|
+
)
|
|
5413
|
+
.join("\n")
|
|
5414
|
+
: "Nothing scheduled."
|
|
5415
|
+
);
|
|
5416
|
+
return 0;
|
|
5417
|
+
}
|
|
5363
5418
|
case "cap": {
|
|
5364
5419
|
const orgId = positionals[2];
|
|
5365
5420
|
const value = positionals[3];
|