@tarout/cli 0.4.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.
Files changed (2) hide show
  1. package/dist/index.js +73 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -61,7 +61,7 @@ import { Command } from "commander";
61
61
  // package.json
62
62
  var package_default = {
63
63
  name: "@tarout/cli",
64
- version: "0.4.0",
64
+ version: "0.5.0",
65
65
  description: "Tarout CLI \u2014 the Saudi cloud platform for coding agents",
66
66
  type: "module",
67
67
  bin: {
@@ -3758,8 +3758,8 @@ async function performBillingChange(client, input2) {
3758
3758
  addons: input2.addons
3759
3759
  });
3760
3760
  } else if (kind === "addon") {
3761
- const addons = input2.addons ?? (input2.addonKey ? [{ addonKey: input2.addonKey, quantity: input2.quantity ?? 1 }] : []);
3762
- result = await client.subscription.purchaseAddons.mutate({ addons });
3761
+ const items = input2.addons ?? (input2.addonKey ? [{ addonKey: input2.addonKey, quantity: input2.quantity ?? 1 }] : []);
3762
+ result = await client.subscription.purchaseAddons.mutate({ items });
3763
3763
  } else {
3764
3764
  result = await client.subscription.setPlanQuantity.mutate({
3765
3765
  quantity: input2.quantity
@@ -3949,6 +3949,46 @@ async function pollCheckoutUntilTerminal(client, orderId, opts) {
3949
3949
  };
3950
3950
  }
3951
3951
 
3952
+ // src/lib/plan-cart.ts
3953
+ function planFamily(planKey) {
3954
+ if (!planKey) return null;
3955
+ if (planKey === "free") return "FREE";
3956
+ if (planKey === "shared" || planKey.startsWith("shared_") || planKey.startsWith("bundle_")) {
3957
+ return "SHARED";
3958
+ }
3959
+ if (planKey === "dedicated" || planKey.startsWith("dedicated_")) {
3960
+ return "DEDICATED";
3961
+ }
3962
+ return null;
3963
+ }
3964
+ function isPaidFamily(planKey) {
3965
+ const family = planFamily(planKey);
3966
+ return family === "SHARED" || family === "DEDICATED";
3967
+ }
3968
+ function resourceAddonKeysForPlan(planKey) {
3969
+ switch (planFamily(planKey)) {
3970
+ case "SHARED":
3971
+ return { dbAddonKey: "db.starter", storageAddonKey: "storage.gb" };
3972
+ case "DEDICATED":
3973
+ return { dbAddonKey: "db.pro", storageAddonKey: "storage.gb" };
3974
+ default:
3975
+ return { dbAddonKey: null, storageAddonKey: null };
3976
+ }
3977
+ }
3978
+ function buildPlanAddonCart(planKey, resources) {
3979
+ const { dbAddonKey, storageAddonKey } = resourceAddonKeysForPlan(planKey);
3980
+ const databases = Math.max(0, Math.floor(resources.databases ?? 0));
3981
+ const storageGb = Math.max(0, Math.floor(resources.storageGb ?? 0));
3982
+ const cart = [];
3983
+ if (dbAddonKey && databases > 0) {
3984
+ cart.push({ addonKey: dbAddonKey, quantity: databases });
3985
+ }
3986
+ if (storageAddonKey && storageGb > 0) {
3987
+ cart.push({ addonKey: storageAddonKey, quantity: storageGb });
3988
+ }
3989
+ return cart;
3990
+ }
3991
+
3952
3992
  // src/commands/billing.ts
3953
3993
  function reportBillingResult(result, label) {
3954
3994
  const code = emitBillingResult(result, { label });
@@ -4078,7 +4118,8 @@ function registerBillingCommands(program2) {
4078
4118
  const client = getApiClient();
4079
4119
  let targetPlan = planKey || options.plan;
4080
4120
  const billingPeriod = options.billingPeriod;
4081
- const addons = Array.isArray(options.addon) && options.addon.length > 0 ? options.addon : void 0;
4121
+ let planQuantity = options.quantity;
4122
+ let addons = Array.isArray(options.addon) && options.addon.length > 0 ? options.addon : void 0;
4082
4123
  if (!targetPlan) {
4083
4124
  const _spinner = startSpinner("Fetching plans...");
4084
4125
  const catalog = await client.subscription.getCatalog.query();
@@ -4109,12 +4150,31 @@ function registerBillingCommands(program2) {
4109
4150
  if (!targetPlan) {
4110
4151
  throw new Error("No plan selected");
4111
4152
  }
4153
+ if (!isJsonMode() && !isNonInteractiveMode() && !shouldSkipConfirmation() && !addons && isPaidFamily(targetPlan)) {
4154
+ if (planQuantity === void 0 && planFamily(targetPlan) === "SHARED") {
4155
+ const apps = parsePositiveInt(
4156
+ await input("How many apps (app slots)?", "1"),
4157
+ 1
4158
+ );
4159
+ planQuantity = Math.max(1, apps);
4160
+ }
4161
+ const databases = parsePositiveInt(
4162
+ await input("How many databases to include?", "1"),
4163
+ 0
4164
+ );
4165
+ const storageGb = parsePositiveInt(
4166
+ await input("Object storage to include (GB, 0 for none)?", "5"),
4167
+ 0
4168
+ );
4169
+ const cart = buildPlanAddonCart(targetPlan, { databases, storageGb });
4170
+ if (cart.length > 0) addons = cart;
4171
+ }
4112
4172
  const _previewSpinner = startSpinner("Calculating change...");
4113
4173
  let preview;
4114
4174
  try {
4115
4175
  preview = await client.subscription.previewPlanChange.query({
4116
4176
  planKey: targetPlan,
4117
- planQuantity: options.quantity,
4177
+ planQuantity,
4118
4178
  billingPeriod,
4119
4179
  addons
4120
4180
  });
@@ -4126,7 +4186,7 @@ function registerBillingCommands(program2) {
4126
4186
  if (!shouldSkipConfirmation()) {
4127
4187
  log("");
4128
4188
  log(`Plan: ${colors.cyan(targetPlan)}`);
4129
- if (options.quantity) log(`Quantity: ${options.quantity}`);
4189
+ if (planQuantity) log(`Quantity: ${planQuantity}`);
4130
4190
  if (billingPeriod) log(`Billing period: ${billingPeriod}`);
4131
4191
  if (addons && addons.length > 0) {
4132
4192
  log(
@@ -4153,7 +4213,7 @@ function registerBillingCommands(program2) {
4153
4213
  flag: "--yes",
4154
4214
  context: {
4155
4215
  plan: targetPlan,
4156
- quantity: options.quantity,
4216
+ quantity: planQuantity,
4157
4217
  billingPeriod,
4158
4218
  addons,
4159
4219
  amountDueHalalas
@@ -4169,7 +4229,7 @@ function registerBillingCommands(program2) {
4169
4229
  const result = await performBillingChange(client, {
4170
4230
  kind: "plan",
4171
4231
  planKey: targetPlan,
4172
- quantity: options.quantity,
4232
+ quantity: planQuantity,
4173
4233
  billingPeriod,
4174
4234
  addons,
4175
4235
  wait: options.wait,
@@ -4461,7 +4521,7 @@ function registerBillingCommands(program2) {
4461
4521
  const client = getApiClient();
4462
4522
  const _spinner = startSpinner("Calculating preview...");
4463
4523
  const preview = await client.subscription.previewAddonsPurchase.query({
4464
- addons: [{ addonKey, quantity: options.quantity || 1 }]
4524
+ items: [{ addonKey, quantity: options.quantity || 1 }]
4465
4525
  });
4466
4526
  succeedSpinner();
4467
4527
  if (isJsonMode()) {
@@ -4771,6 +4831,10 @@ function collectAddon(value, previous) {
4771
4831
  }
4772
4832
  return [...previous, { addonKey, quantity }];
4773
4833
  }
4834
+ function parsePositiveInt(raw, fallback) {
4835
+ const n = Number.parseInt(String(raw).trim(), 10);
4836
+ return Number.isFinite(n) && n >= 0 ? n : fallback;
4837
+ }
4774
4838
  function parseBillingPeriod(raw) {
4775
4839
  const v = raw.toLowerCase();
4776
4840
  if (v === "monthly" || v === "yearly") return v;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tarout/cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Tarout CLI — the Saudi cloud platform for coding agents",
5
5
  "type": "module",
6
6
  "bin": {