wawesome 0.23.0 → 0.25.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.
@@ -15,13 +15,16 @@ var GatewayError = class extends Error {
15
15
  /** The raw response, for `--verbose` to print when the prose is not enough. */
16
16
  body;
17
17
  traceId;
18
- constructor(message, status, reason, body = "", traceId) {
18
+ /** When a `locked` rename refusal says the next rename is allowed. */
19
+ renamableAt;
20
+ constructor(message, status, reason, body = "", traceId, renamableAt) {
19
21
  super(traceId ? `${message}\n${traceLine(traceId)}` : message);
20
22
  this.name = "GatewayError";
21
23
  this.status = status;
22
24
  this.reason = reason;
23
25
  this.body = body;
24
26
  this.traceId = traceId;
27
+ this.renamableAt = renamableAt;
25
28
  }
26
29
  };
27
30
  function traceLine(traceId) {
@@ -46,7 +49,7 @@ async function asGatewayError(res, fallback) {
46
49
  function rejectionOf(body, status, fallback, traceId) {
47
50
  try {
48
51
  const parsed = JSON.parse(body);
49
- return new GatewayError(parsed.error || fallback, status, parsed.reason, body, parsed.trace_id || traceId);
52
+ return new GatewayError(parsed.error || fallback, status, parsed.reason, body, parsed.trace_id || traceId, parsed.renamable_at);
50
53
  } catch {
51
54
  return new GatewayError(fallback, status, void 0, body, traceId);
52
55
  }
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as asGatewayError, E as rejectionOf, S as GatewayError, T as reasonOf, a as manifestOf, b as reportSessionCommandRefused, c as getDashboardUrl, d as readCredentials, f as readFunctionConfig, g as CREDENTIAL_ENV_VAR, h as writeCredentials, l as getFunctionConfigPath, m as resolveGatewayUrlWithoutSession, n as deployDigest, o as LOGIN_CALLBACK_PORT, p as resolveDashboardUrlForLogin, r as isDocument, s as deleteCredentials, t as collectAssets, u as getGatewayUrl, v as credentialFromEnvironment, w as errorText, x as unauthorizedMessage, y as credentialPrefix } from "./assets-CtoyN8P3.mjs";
1
+ import { C as asGatewayError, E as rejectionOf, S as GatewayError, T as reasonOf, a as manifestOf, b as reportSessionCommandRefused, c as getDashboardUrl, d as readCredentials, f as readFunctionConfig, g as CREDENTIAL_ENV_VAR, h as writeCredentials, l as getFunctionConfigPath, m as resolveGatewayUrlWithoutSession, n as deployDigest, o as LOGIN_CALLBACK_PORT, p as resolveDashboardUrlForLogin, r as isDocument, s as deleteCredentials, t as collectAssets, u as getGatewayUrl, v as credentialFromEnvironment, w as errorText, x as unauthorizedMessage, y as credentialPrefix } from "./assets-Cgw3_rAq.mjs";
2
2
  import { i as polyfilledGlobals, n as declaredModules, o as unsupportedGlobals, r as methodRemedy, t as declaredMethods } from "./guest-surface-BwrNP2Cz.mjs";
3
3
  import cac from "cac";
4
4
  import fs from "node:fs";
@@ -11,7 +11,7 @@ import crypto from "node:crypto";
11
11
  import http from "node:http";
12
12
  import { Readable } from "node:stream";
13
13
  import readline from "node:readline";
14
- import { confirm, select } from "@inquirer/prompts";
14
+ import { confirm, input, select } from "@inquirer/prompts";
15
15
  import zlib from "node:zlib";
16
16
  //#region src/brand.ts
17
17
  const PLAIN = "[w] wawesome";
@@ -687,7 +687,7 @@ async function buildHandler(entryInput, config, options) {
687
687
  * that has to name this version — `--version`, the dependency a scaffolded
688
688
  * project pins — reads it here, so a release bumps one file.
689
689
  */
690
- const CLI_VERSION = "0.23.0";
690
+ const CLI_VERSION = "0.25.0";
691
691
  //#endregion
692
692
  //#region src/cli-login.ts
693
693
  const START_PATH = "/v1/cli/login/start";
@@ -1067,6 +1067,44 @@ function endSession(said) {
1067
1067
  process.exit(1);
1068
1068
  }
1069
1069
  //#endregion
1070
+ //#region src/schedules.ts
1071
+ /**
1072
+ * When a schedule next runs, or why it does not run at all.
1073
+ *
1074
+ * The three ways of being off never render alike, and a schedule that is off
1075
+ * twice over says so: someone who reads only the pause will declare it again,
1076
+ * press resume, and file a bug when neither starts it.
1077
+ */
1078
+ function whenItRuns(schedule) {
1079
+ const undeclared = schedule.declared === false;
1080
+ if (schedule.state === "suspended") {
1081
+ const why = "The workspace owes payment, its subscription ended, or it has spent past its plan's allowance";
1082
+ return undeclared ? `suspended, and not in this config file. ${why}; declare it again too` : `suspended. ${why}`;
1083
+ }
1084
+ if (schedule.state === "paused") return undeclared ? "paused, and not in this config file. Declare it again, then resume" : "paused. Resume it to run again";
1085
+ if (undeclared) return "not in this config file, so it is disabled. Its history is kept";
1086
+ if (schedule.state !== "active") return schedule.state;
1087
+ return schedule.next_fire_at ? `next run ${asUtc$1(schedule.next_fire_at)}` : "next run unknown";
1088
+ }
1089
+ /** `2026-08-23 03:00 UTC`, which is the zone every expression is read in. */
1090
+ function asUtc$1(iso) {
1091
+ const at = new Date(iso);
1092
+ if (Number.isNaN(at.getTime())) return iso;
1093
+ const pad = (n) => String(n).padStart(2, "0");
1094
+ return `${at.getUTCFullYear()}-${pad(at.getUTCMonth() + 1)}-${pad(at.getUTCDate())} ${pad(at.getUTCHours())}:${pad(at.getUTCMinutes())} UTC`;
1095
+ }
1096
+ /**
1097
+ * The block a deploy prints for the schedules it just applied. Every schedule
1098
+ * appears, including the ones that are off, so putting recurring compute on the
1099
+ * bill — or taking it off — is never silent.
1100
+ */
1101
+ function scheduleLines(schedules) {
1102
+ if (schedules.length === 0) return [];
1103
+ const nameWidth = Math.max(...schedules.map((s) => s.name.length));
1104
+ const expressionWidth = Math.max(...schedules.map((s) => s.expression.length));
1105
+ return [" Schedules:", ...[...schedules].sort((a, b) => a.name.localeCompare(b.name)).map((schedule) => ` ${schedule.name.padEnd(nameWidth)} ${schedule.expression.padEnd(expressionWidth)} ${whenItRuns(schedule)}`)];
1106
+ }
1107
+ //#endregion
1070
1108
  //#region src/tenant.ts
1071
1109
  async function fetchTenantDetails(creds) {
1072
1110
  const res = await authorizedFetch(`${creds.gateway_url}/v1/tenant`, { headers: { Authorization: `Bearer ${creds.tenant_jwt}` } });
@@ -1102,8 +1140,12 @@ async function resolveWorkspace(creds) {
1102
1140
  * telling a user different things about the same reason — and `retryable` is
1103
1141
  * what separates a name worth retyping from one that no name would fix.
1104
1142
  */
1105
- function renameAdvice(reason) {
1106
- switch (reason) {
1143
+ function renameAdvice(err) {
1144
+ if (!(err instanceof GatewayError)) return {
1145
+ text: "",
1146
+ retryable: false
1147
+ };
1148
+ switch (err.reason) {
1107
1149
  case "taken":
1108
1150
  case "reserved": return {
1109
1151
  text: "Pick a different name.",
@@ -1118,7 +1160,7 @@ function renameAdvice(reason) {
1118
1160
  retryable: true
1119
1161
  };
1120
1162
  case "locked": return {
1121
- text: "A deploy landed while this was running, which fixed the address for good.",
1163
+ text: err.renamableAt ? nextRenameAllowed(err.renamableAt) : "",
1122
1164
  retryable: false
1123
1165
  };
1124
1166
  default: return {
@@ -1127,6 +1169,9 @@ function renameAdvice(reason) {
1127
1169
  };
1128
1170
  }
1129
1171
  }
1172
+ function nextRenameAllowed(renamableAt) {
1173
+ return `The next rename is allowed from ${asUtc$1(renamableAt)}.`;
1174
+ }
1130
1175
  /**
1131
1176
  * Ask for the workspace's public address to become `slug`.
1132
1177
  *
@@ -1306,44 +1351,6 @@ async function reportCredential(creds) {
1306
1351
  console.log("");
1307
1352
  }
1308
1353
  //#endregion
1309
- //#region src/schedules.ts
1310
- /**
1311
- * When a schedule next runs, or why it does not run at all.
1312
- *
1313
- * The three ways of being off never render alike, and a schedule that is off
1314
- * twice over says so: someone who reads only the pause will declare it again,
1315
- * press resume, and file a bug when neither starts it.
1316
- */
1317
- function whenItRuns(schedule) {
1318
- const undeclared = schedule.declared === false;
1319
- if (schedule.state === "suspended") {
1320
- const why = "The workspace owes payment, its subscription ended, or it has spent past its plan's allowance";
1321
- return undeclared ? `suspended, and not in this config file. ${why}; declare it again too` : `suspended. ${why}`;
1322
- }
1323
- if (schedule.state === "paused") return undeclared ? "paused, and not in this config file. Declare it again, then resume" : "paused. Resume it to run again";
1324
- if (undeclared) return "not in this config file, so it is disabled. Its history is kept";
1325
- if (schedule.state !== "active") return schedule.state;
1326
- return schedule.next_fire_at ? `next run ${asUtc$1(schedule.next_fire_at)}` : "next run unknown";
1327
- }
1328
- /** `2026-08-23 03:00 UTC`, which is the zone every expression is read in. */
1329
- function asUtc$1(iso) {
1330
- const at = new Date(iso);
1331
- if (Number.isNaN(at.getTime())) return iso;
1332
- const pad = (n) => String(n).padStart(2, "0");
1333
- return `${at.getUTCFullYear()}-${pad(at.getUTCMonth() + 1)}-${pad(at.getUTCDate())} ${pad(at.getUTCHours())}:${pad(at.getUTCMinutes())} UTC`;
1334
- }
1335
- /**
1336
- * The block a deploy prints for the schedules it just applied. Every schedule
1337
- * appears, including the ones that are off, so putting recurring compute on the
1338
- * bill — or taking it off — is never silent.
1339
- */
1340
- function scheduleLines(schedules) {
1341
- if (schedules.length === 0) return [];
1342
- const nameWidth = Math.max(...schedules.map((s) => s.name.length));
1343
- const expressionWidth = Math.max(...schedules.map((s) => s.expression.length));
1344
- return [" Schedules:", ...[...schedules].sort((a, b) => a.name.localeCompare(b.name)).map((schedule) => ` ${schedule.name.padEnd(nameWidth)} ${schedule.expression.padEnd(expressionWidth)} ${whenItRuns(schedule)}`)];
1345
- }
1346
- //#endregion
1347
1354
  //#region src/billing.ts
1348
1355
  function billingPageUrl() {
1349
1356
  const base = getDashboardUrl().replace(/\/+$/, "");
@@ -2978,6 +2985,10 @@ function reportPublishRefusal(message) {
2978
2985
  console.error("[wawesome] Re-run with \x1B[36mwawesome deploy --publish\x1B[0m to publish it, or put");
2979
2986
  console.error("[wawesome] \x1B[36m\"visibility\": \"private\"\x1B[0m back in wawesome-function.json.\n");
2980
2987
  }
2988
+ function reportAlreadyLive(message) {
2989
+ console.log(`[wawesome] ${message}`);
2990
+ process.exit(0);
2991
+ }
2981
2992
  /**
2982
2993
  * Deploy a function: build → upload JS to gateway → promote.
2983
2994
  */
@@ -3098,6 +3109,7 @@ async function deploy(entryInput, options) {
3098
3109
  console.error(`\n[wawesome] \x1b[31mError: ${refusal.message}\x1b[0m`);
3099
3110
  console.error(`[wawesome] ${planLimitAdvice(refusal.reason)}\n`);
3100
3111
  } else if (uploadRes.status === 409) {
3112
+ if (refusal.reason === "already-live") reportAlreadyLive(refusal.message);
3101
3113
  if (refusal.reason === "publish-needs-confirmation") {
3102
3114
  reportPublishRefusal(refusal.message);
3103
3115
  process.exit(1);
@@ -3258,12 +3270,13 @@ async function uploadAssets(creds, app, funcName, bundle, { assets, privateFiles
3258
3270
  return;
3259
3271
  }
3260
3272
  const refusal = rejectionOf(errorBody, manifestRes.status, "This deploy is already deployed.");
3273
+ if (refusal.reason === "already-live") reportAlreadyLive(refusal.message);
3261
3274
  if (refusal.reason === "publish-needs-confirmation") {
3262
3275
  reportPublishRefusal(refusal.message);
3263
3276
  process.exit(1);
3264
3277
  }
3265
3278
  console.error(`\n[wawesome] \x1b[31mError: ${refusal.message}\x1b[0m`);
3266
- console.error("[wawesome] Nothing changed since the last deploy, so nothing was uploaded.\n");
3279
+ console.error("[wawesome] Nothing was uploaded.\n");
3267
3280
  } else {
3268
3281
  const refusal = rejectionOf(errorBody, manifestRes.status, `Asset manifest failed (HTTP ${manifestRes.status}).`);
3269
3282
  console.error(`[wawesome] Error: ${refusal.message}`);
@@ -4255,18 +4268,19 @@ function announceUrl(surface, slug, appSlug, functionName) {
4255
4268
  console.log(` ${SUBTREE_NOTE}\n`);
4256
4269
  }
4257
4270
  /**
4258
- * Show the URL, and offer to fix the workspace address while it can still be fixed.
4271
+ * Show the URL, and offer to change the workspace address while a rename is free.
4259
4272
  *
4260
- * This is the last moment that address is free: it locks the first time a
4261
- * version is promoted, which is what the deploy at the end of this flow does.
4262
- * Asking here rather than at signup is the whole reason naming was deferred —
4263
- * it is client-facing branding, and nobody chooses it well before seeing the
4264
- * product work. The URL comes first so the offer is about something concrete.
4273
+ * This is the last moment a rename costs nothing: after the first promotion,
4274
+ * which the deploy at the end of this flow does, the old name redirects and
4275
+ * renames wait 30 days apart. Asking here rather than at signup is the whole
4276
+ * reason naming was deferred — it is client-facing branding, and nobody chooses
4277
+ * it well before seeing the product work. The URL comes first so the offer is
4278
+ * about something concrete.
4265
4279
  *
4266
- * The lock is read from the gateway rather than guessed, so a user who cannot
4267
- * rename is told why instead of being walked into a rejection. Nothing here can
4268
- * fail the flow: the project is already on disk and the deploy still works under
4269
- * the address the workspace has.
4280
+ * A published workspace is not offered one: its rename moves live links, and
4281
+ * `wawesome workspace rename` is where that is confirmed. Nothing here can fail
4282
+ * the flow: the project is already on disk and the deploy still works under the
4283
+ * address the workspace has.
4270
4284
  */
4271
4285
  async function offerWorkspaceAddress(session, creds, tenant, appSlug, functionName) {
4272
4286
  const current = tenant?.tenant_slug ?? creds.tenant_slug;
@@ -4278,13 +4292,14 @@ async function offerWorkspaceAddress(session, creds, tenant, appSlug, functionNa
4278
4292
  console.log(" is a question for the gateway, which did not answer.\n");
4279
4293
  return;
4280
4294
  }
4281
- if (tenant.slug_locked) {
4282
- console.log(` 🔒 '${current}' is fixed. A Function version has been promoted, and live URLs already carry it.\n`);
4295
+ if (tenant.published) {
4296
+ console.log(` '${current}' is your workspace address. It is already live, so change it`);
4297
+ console.log(" with: wawesome workspace rename <name>\n");
4283
4298
  return;
4284
4299
  }
4285
4300
  console.log(` '${current}' is your workspace address, the part of that URL that is`);
4286
- console.log(" yours rather than this project's. Now is the moment to change it. It");
4287
- console.log(" locks for good the first time you deploy, because live URLs carry it.");
4301
+ console.log(" yours rather than this project's. Now is a good moment to change it.");
4302
+ console.log(" You can change it later too, once every 30 days after your first deploy.");
4288
4303
  console.log(" Press enter to keep it.\n");
4289
4304
  let refusal;
4290
4305
  for (let attempt = 0; attempt < MAX_RENAME_ATTEMPTS; attempt++) {
@@ -4301,7 +4316,7 @@ async function offerWorkspaceAddress(session, creds, tenant, appSlug, functionNa
4301
4316
  } catch (err) {
4302
4317
  console.log(`[wawesome] ${errorText(err)}`);
4303
4318
  refusal = reasonOf(err);
4304
- const { text, retryable } = renameAdvice(refusal);
4319
+ const { text, retryable } = renameAdvice(err);
4305
4320
  if (text) console.log(`[wawesome] ${text}`);
4306
4321
  if (!retryable) break;
4307
4322
  }
@@ -5521,20 +5536,27 @@ async function showWorkspace(options) {
5521
5536
  console.log(` ${SUBTREE_NOTE}`);
5522
5537
  }
5523
5538
  }
5524
- if (tenant.slug_locked) console.log("\n 🔒 The address is fixed. A Function version has been promoted, and live URLs carry it.");
5525
- else {
5526
- console.log("\n The address can still be changed: \x1B[36mwawesome workspace rename <name>\x1B[0m");
5527
- console.log(" It locks for good the first time you deploy.");
5539
+ const waitUntil = renameWaitsUntil(tenant);
5540
+ if (waitUntil) {
5541
+ console.log(`\n The address can be changed again from ${asUtc$1(waitUntil)}.`);
5542
+ console.log(" One rename is allowed every 30 days.");
5543
+ } else {
5544
+ console.log("\n The address can be changed: \x1B[36mwawesome workspace rename <name>\x1B[0m");
5545
+ console.log(tenant.published ? " The old address then redirects to the new one for 90 days. One rename every 30 days." : " Rename it freely until your first deploy. After that, once every 30 days.");
5528
5546
  }
5529
5547
  console.log("");
5530
5548
  }
5549
+ function renameWaitsUntil(tenant) {
5550
+ if (!tenant.renamable_at) return null;
5551
+ return new Date(tenant.renamable_at).getTime() > Date.now() ? tenant.renamable_at : null;
5552
+ }
5531
5553
  /**
5532
5554
  * Change the workspace's public address.
5533
5555
  *
5534
- * The lock is read from the gateway before asking, so a user who cannot rename
5535
- * is told why instead of being walked into a rejection. The rejection is still
5536
- * handled: a promotion landing between the two calls is the one case where the
5537
- * gateway knows something this command could not.
5556
+ * The 30-day wait is read from the gateway before asking, so a user who cannot
5557
+ * rename is told when they can instead of being walked into a rejection. The
5558
+ * rejection is still handled: another rename landing between the two calls is
5559
+ * something only the gateway knows.
5538
5560
  */
5539
5561
  async function renameWorkspace(slug, options) {
5540
5562
  const creds = requireCredentials$1();
@@ -5545,24 +5567,27 @@ async function renameWorkspace(slug, options) {
5545
5567
  }
5546
5568
  try {
5547
5569
  const tenant = await fetchTenantDetails(creds);
5548
- if (tenant.slug_locked) {
5549
- console.error("\n[wawesome] \x1B[31mThe workspace address can no longer be changed.\x1B[0m");
5550
- console.error(`[wawesome] '${tenant.tenant_slug}' is fixed: a Function version has been promoted, and live URLs already carry it.`);
5570
+ const waitUntil = renameWaitsUntil(tenant);
5571
+ if (waitUntil) {
5572
+ console.error("\n[wawesome] \x1B[31mThe workspace address cannot be changed yet.\x1B[0m");
5573
+ console.error(`[wawesome] It was renamed less than 30 days ago. ${nextRenameAllowed(waitUntil)}`);
5551
5574
  process.exit(1);
5552
5575
  return;
5553
5576
  }
5554
- if (options.verbose) console.log(`[wawesome:verbose] Renaming '${tenant.tenant_slug}' → '${slug}'`);
5555
- const result = await renameTenantSlug(creds, slug.trim());
5577
+ const typed = slug.trim();
5578
+ if (tenant.published && !options.yes) await confirmRename(tenant.tenant_slug, typed);
5579
+ if (options.verbose) console.log(`[wawesome:verbose] Renaming '${tenant.tenant_slug}' → '${typed}'`);
5580
+ const result = await renameTenantSlug(creds, typed);
5556
5581
  console.log("\n======================================================");
5557
5582
  console.log("✅ \x1B[32mWORKSPACE RENAMED\x1B[0m");
5558
5583
  console.log("======================================================");
5559
5584
  console.log(`\n Address: ${result.tenant_slug}`);
5560
- console.log(` Previous: ${result.previous_slug} (no longer resolves)`);
5585
+ console.log(tenant.published ? ` Previous: ${result.previous_slug} (redirects to the new address for 90 days)` : ` Previous: ${result.previous_slug} (no longer resolves)`);
5561
5586
  console.log("======================================================\n");
5562
5587
  } catch (err) {
5563
5588
  if (err instanceof GatewayError) {
5564
5589
  console.error(`\n[wawesome] \x1b[31m${err.message}\x1b[0m`);
5565
- const { text } = renameAdvice(err.reason);
5590
+ const { text } = renameAdvice(err);
5566
5591
  if (text) console.error(`[wawesome] ${text}`);
5567
5592
  console.error("");
5568
5593
  process.exit(1);
@@ -5573,6 +5598,32 @@ async function renameWorkspace(slug, options) {
5573
5598
  }
5574
5599
  }
5575
5600
  /**
5601
+ * Links are already out under a published address, so the new name is typed
5602
+ * twice, as the dashboard asks: a typo here would move every client's URL.
5603
+ */
5604
+ async function confirmRename(current, next) {
5605
+ if (!isInteractive()) {
5606
+ console.error("\n[wawesome] \x1B[31mA rename after publishing asks for confirmation, and there is nobody to ask.\x1B[0m");
5607
+ console.error(`[wawesome] Pass --yes to rename '${current}' to '${next}' without being asked.`);
5608
+ process.exit(1);
5609
+ }
5610
+ console.log(`\n Rename '${current}' to '${next}'?`);
5611
+ console.log(` - The new address is '${next}'.`);
5612
+ console.log(` - '${current}' redirects to the new address for 90 days. After that it is held`);
5613
+ console.log(" for 90 more days, and only you can take it back.");
5614
+ console.log(" - Open preview links stop working now.\n");
5615
+ let retyped;
5616
+ try {
5617
+ retyped = await input({ message: "Type the new address again to confirm:" });
5618
+ } catch {
5619
+ retyped = "";
5620
+ }
5621
+ if (retyped.trim() !== next) {
5622
+ console.error(`[wawesome] Cancelled. The address is still '${current}'.`);
5623
+ process.exit(1);
5624
+ }
5625
+ }
5626
+ /**
5576
5627
  * The workspaces this person belongs to, with the one the session is in
5577
5628
  * marked.
5578
5629
  *
@@ -6432,7 +6483,7 @@ cli.command("domains detach <hostname>", "Stop serving the current app at a doma
6432
6483
  cli.command("login", "Authenticate with the wawesome.io platform").option("--api <url>", "API URL (default: https://api.wawesome.io)").option("--gateway <url>", "Alias for --api <url>").option("--dashboard <url>", "Dashboard URL to record (default: the one the platform names)").option("-v, --verbose", "Enable verbose debug output").action((options) => login(options));
6433
6484
  cli.command("logout", "Clear stored authentication credentials").action(async () => await logout());
6434
6485
  cli.command("whoami", "Show current login session info").action(() => whoami());
6435
- cli.command("workspace [action] [name]", "Show the workspace, move between workspaces, or rename the public address").usage("workspace <action> [name]\n\nActions:\n show Show the workspace name, address, and whether it can still change\n list (ls) Show the workspaces you belong to, and which one you are in\n switch <name> Move this terminal to another workspace you belong to\n rename <name> Change the public address, while nothing live depends on it").example("wawesome workspace").example("wawesome workspace list").example("wawesome workspace switch northwind").example("wawesome workspace rename northwind").option("-v, --verbose", "Enable verbose debug output").action((action, name, options) => workspaceCommand(action, name, options));
6486
+ cli.command("workspace [action] [name]", "Show the workspace, move between workspaces, or rename the public address").usage("workspace <action> [name]\n\nActions:\n show Show the workspace name, address, and whether it can still change\n list (ls) Show the workspaces you belong to, and which one you are in\n switch <name> Move this terminal to another workspace you belong to\n rename <name> Change the public address. After your first deploy, once every 30 days").example("wawesome workspace").example("wawesome workspace list").example("wawesome workspace switch northwind").example("wawesome workspace rename northwind").option("-y, --yes", "Rename without typing the new address again").option("-v, --verbose", "Enable verbose debug output").action((action, name, options) => workspaceCommand(action, name, options));
6436
6487
  cli.command("export [action]", "Export the whole workspace as one archive, and print the link to it").usage("export [status]\n\nWith no action, asks for an export and waits until it is ready.\n status Show the latest export, and a new link if it is ready").example("wawesome export").example("wawesome export status").option("--no-wait", "Ask for the export and return without waiting for it").option("-v, --verbose", "Enable verbose debug output").action((action, options) => exportCommand(action, options));
6437
6488
  cli.command("templates [action]", "Browse the template catalog").usage("templates [action]\n\nActions:\n list (ls) Show every available template (default)").example("wawesome templates").example("wawesome templates list").option("--api <url>", "API URL (default: https://api.wawesome.io)").option("-v, --verbose", "Enable verbose debug output").action((action, options) => templatesCommand(action, options));
6438
6489
  cli.command("credentials [action] [target]", "Mint, list, regenerate, revoke and delete deploy credentials").alias("credential").usage(`credentials <action> [options]
@@ -1,4 +1,4 @@
1
- import { f as readFunctionConfig, i as listFiles } from "./assets-CtoyN8P3.mjs";
1
+ import { f as readFunctionConfig, i as listFiles } from "./assets-Cgw3_rAq.mjs";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  //#region ../../server/guest-surface/private-files.js
@@ -1,2 +1,2 @@
1
- import { n as localModule, r as privateFilesDir, t as MAX_PRIVATE_FILE_READ_BYTES } from "./local-modules-CAHr4SPW.mjs";
1
+ import { n as localModule, r as privateFilesDir, t as MAX_PRIVATE_FILE_READ_BYTES } from "./local-modules-DvEInmfO.mjs";
2
2
  export { MAX_PRIVATE_FILE_READ_BYTES, localModule, privateFilesDir };
package/dist/vite.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { i as polyfilledGlobals, n as declaredModules, o as unsupportedGlobals, r as methodRemedy, t as declaredMethods } from "./guest-surface-BwrNP2Cz.mjs";
2
- import { n as localModule, r as privateFilesDir, t as MAX_PRIVATE_FILE_READ_BYTES } from "./local-modules-CAHr4SPW.mjs";
2
+ import { n as localModule, r as privateFilesDir, t as MAX_PRIVATE_FILE_READ_BYTES } from "./local-modules-DvEInmfO.mjs";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
@@ -1,6 +1,6 @@
1
1
  import { n as declaredModules } from "./guest-surface-BwrNP2Cz.mjs";
2
2
  import { t as applyGuestParity } from "./guest-parity-DA7x-8BC.mjs";
3
- import { n as localModule } from "./local-modules-CAHr4SPW.mjs";
3
+ import { n as localModule } from "./local-modules-DvEInmfO.mjs";
4
4
  import { vi } from "vitest";
5
5
  //#region src/vitest-setup.ts
6
6
  applyGuestParity();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wawesome",
3
- "version": "0.23.0",
3
+ "version": "0.25.0",
4
4
  "description": "CLI tool for building and deploying serverless functions on wawesome.io platform",
5
5
  "license": "MIT",
6
6
  "type": "module",