Skip to content

Commit 335911b

Browse files
feat: add requireInGoodStanding meta property (#44)
Co-authored-by: Jared Lunde <98760247+jared-paperspace@users.noreply.github.com>
1 parent b06630b commit 335911b

16 files changed

Lines changed: 270 additions & 7 deletions

File tree

api/billing.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { client } from "./client.ts";
2+
3+
export const billingAccountStanding = {
4+
get: client("/billing/account-standing").get,
5+
};

commands/autoscaling-group/create/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export const create = command("create", {
5656
// set. If not, we'll throw an error.
5757
meta: {
5858
requireApiKey: true,
59+
requireInGoodStanding: true,
5960
},
6061
}).run(
6162
async function* ({ flags }) {

commands/autoscaling-group/update/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export const update = command("update", {
6363
// set. If not, we'll throw an error.
6464
meta: {
6565
requireApiKey: true,
66+
requireInGoodStanding: true,
6667
},
6768
}).run(
6869
async function* ({ args, flags }) {

commands/deployment/up/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const up = command("up", {
4141
// set. If not, we'll throw an error.
4242
meta: {
4343
requireApiKey: true,
44+
requireInGoodStanding: true,
4445
},
4546
}).run(async function* ({ flags, ctx }) {
4647
for await (const line of runUp({ flags, ctx })) {

commands/machine/create/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export const create = command("create", {
9696
// set. If not, we'll throw an error.
9797
meta: {
9898
requireApiKey: true,
99+
requireInGoodStanding: true,
99100
},
100101
}).run(
101102
async function* ({ flags }) {

commands/machine/start/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export const start = command("start", {
3030
// set. If not, we'll throw an error.
3131
meta: {
3232
requireApiKey: true,
33+
requireInGoodStanding: true,
3334
},
3435
}).run(
3536
async function* ({ args, flags }) {

commands/machine/update/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ export const update = command("update", {
7979
// set. If not, we'll throw an error.
8080
meta: {
8181
requireApiKey: true,
82+
requireInGoodStanding: true,
8283
},
8384
}).run(
8485
async function* ({ args, flags }) {

commands/mod.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import { snapshot } from "./snapshot/mod.ts";
2828
import { template } from "./template/mod.ts";
2929
import { startupScript } from "./startup-script/mod.ts";
3030
import { autoscalingGroup } from "./autoscaling-group/mod.ts";
31+
import { billingAccountStanding } from "../api/billing.ts";
32+
import { asserts } from "../lib/asserts.ts";
3133

3234
/**
3335
* This variable is automatically generated by `zcli add`. Do not remove this
@@ -107,9 +109,13 @@ export const root = app
107109
}
108110
}
109111

112+
// requireInGoodStanding implies requireApiKey.
113+
const requireApiKey = ctx.cmd.meta.requireApiKey ||
114+
ctx.cmd.meta.requireInGoodStanding;
115+
110116
// Check to see if this command requires an API key. If it does, we'll
111117
// check to see if one is set. If not, we'll throw an error.
112-
if (ctx.cmd.meta.requireApiKey && !env.get("PAPERSPACE_API_KEY")) {
118+
if (requireApiKey && !env.get("PAPERSPACE_API_KEY")) {
113119
const availableTeams = Object.keys(await credentials.get("keys"));
114120
const hasTeams = availableTeams.length > 0;
115121
const loginHelper = !hasTeams
@@ -130,6 +136,26 @@ export const root = app
130136

131137
throw new AppError({ message: `${selectMessage}\n${loginHelper}` });
132138
}
139+
140+
if (ctx.cmd.meta.requireInGoodStanding) {
141+
const accountStanding = await billingAccountStanding.get(null);
142+
asserts(accountStanding.ok, accountStanding);
143+
144+
if (!accountStanding.data.isInGoodStanding) {
145+
const team = await appConfig.get("team");
146+
147+
asserts(team, "Log in to continue.");
148+
149+
const billingUrl = new URL(
150+
`/${team}/settings/billing`,
151+
env.get("PAPERSPACE_CONSOLE_URL"),
152+
);
153+
154+
throw new AppError({
155+
message: `Add a credit card to continue\n\n${billingUrl}`,
156+
});
157+
}
158+
}
133159
})
134160
// This function runs after every command.
135161
.persistentPostRun(async function* ({ flags, ctx }) {

commands/private-network/create/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const create = command("create", {
3434
// set. If not, we'll throw an error.
3535
meta: {
3636
requireApiKey: true,
37+
requireInGoodStanding: true,
3738
},
3839
}).run(
3940
async function* ({ flags }) {

commands/public-ip/claim/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const claim = command("claim", {
3232
// set. If not, we'll throw an error.
3333
meta: {
3434
requireApiKey: true,
35+
requireInGoodStanding: true,
3536
},
3637
}).run(
3738
async function* ({ flags }) {

0 commit comments

Comments
 (0)