@wervt/cli 0.2.18 → 0.2.19

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.mjs CHANGED
@@ -420,6 +420,13 @@ function resolveAppDir(arg = ".") {
420
420
  if (existsSync(join("apps", arg, "package.json"))) return resolve("apps", arg);
421
421
  throw new Error(`No app found at ${arg}`);
422
422
  }
423
+ const PREVIEW_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
424
+ /** `todos--pr-12` for `--preview pr-12`: the preview's own app name (control's previews.ts). */
425
+ function previewName(app, preview) {
426
+ if (preview === void 0) return app;
427
+ if (!PREVIEW_RE.test(preview)) throw new Error(`--preview must be lowercase letters, digits and dashes, like pr-12`);
428
+ return `${app}--${preview}`;
429
+ }
423
430
  async function appName(dir, name) {
424
431
  if (!name) {
425
432
  const pkg = JSON.parse(await readFile(join(dir, "package.json"), "utf8"));
@@ -444,6 +451,10 @@ const deploy = defineCommand({
444
451
  type: "string",
445
452
  description: "App name (default: package.json name)"
446
453
  },
454
+ preview: {
455
+ type: "string",
456
+ description: "Deploy a preview of the app instead, at <app>--<preview> (like pr-12): own empty database, the app's access and env plus its preview env"
457
+ },
447
458
  build: {
448
459
  type: "boolean",
449
460
  default: true,
@@ -466,7 +477,7 @@ const deploy = defineCommand({
466
477
  },
467
478
  async run({ args }) {
468
479
  const dir = resolveAppDir(args.dir);
469
- const name = await appName(dir, args.name);
480
+ const name = previewName(await appName(dir, args.name), args.preview);
470
481
  p.intro(`wervt deploy ${name}`);
471
482
  if (args.build) {
472
483
  const pm = (await detectPackageManager(dir))?.name ?? "npm";
@@ -912,6 +923,10 @@ const env = defineCommand({
912
923
  type: "string",
913
924
  description: "KEY (comma separated)"
914
925
  },
926
+ preview: {
927
+ type: "boolean",
928
+ description: "The app's preview env instead: set on top of its env in every preview, from their next deploy"
929
+ },
915
930
  ...connection
916
931
  },
917
932
  async run({ args, rawArgs }) {
@@ -922,17 +937,18 @@ const env = defineCommand({
922
937
  return [pair.slice(0, i), pair.slice(i + 1)];
923
938
  }));
924
939
  const unset = toList(args.unset);
925
- const { keys, warnings = [] } = await (Object.keys(set).length || unset.length ? await api(`/v1/apps/${args.app}/env`, args, {
940
+ const path = `/v1/apps/${args.app}/${args.preview ? "preview-env" : "env"}`;
941
+ const { keys, warnings = [] } = await (Object.keys(set).length || unset.length ? await api(path, args, {
926
942
  method: "PATCH",
927
943
  headers: { "content-type": "application/json" },
928
944
  body: JSON.stringify({
929
945
  set,
930
946
  unset
931
947
  })
932
- }) : await api(`/v1/apps/${args.app}/env`, args)).json();
948
+ }) : await api(path, args)).json();
933
949
  console.log(keys.length ? keys.join("\n") : "No variables set.");
934
950
  for (const warning of warnings) console.error(styleText("yellow", `Warning: ${warning}`));
935
- if (Object.keys(set).length || unset.length) console.log("Applies from the next request.");
951
+ if (Object.keys(set).length || unset.length) console.log(args.preview ? "Previews get it with their next deploy." : "Applies from the next request.");
936
952
  }
937
953
  });
938
954
  const SIZE_FLAGS = [
@@ -1074,7 +1090,7 @@ const tokens = defineCommand({
1074
1090
  })).json();
1075
1091
  console.error(`Deploy token "${token.name}" for ${args.app} (shown once):`);
1076
1092
  console.log(token.token);
1077
- console.error(styleText("dim", "It can deploy this app and nothing else. Store it as the WERVT_TOKEN secret."));
1093
+ console.error(styleText("dim", "It can deploy this app and its previews, nothing else. Store it as the WERVT_TOKEN secret."));
1078
1094
  return;
1079
1095
  }
1080
1096
  if (args.revoke) {
@@ -1377,13 +1393,17 @@ const tasks = defineCommand({
1377
1393
  const remove = defineCommand({
1378
1394
  meta: {
1379
1395
  name: "delete",
1380
- description: "Delete an app (releases, access, env)"
1396
+ description: "Delete an app (releases, access, env) or one of its previews"
1381
1397
  },
1382
1398
  args: {
1383
1399
  app: {
1384
1400
  type: "positional",
1385
- required: true,
1386
- description: "App name"
1401
+ required: false,
1402
+ description: "App name (default: package.json name in the current directory)"
1403
+ },
1404
+ preview: {
1405
+ type: "string",
1406
+ description: "Delete the preview <app>--<preview> (like pr-12) and its data instead"
1387
1407
  },
1388
1408
  "drop-database": {
1389
1409
  type: "boolean",
@@ -1396,16 +1416,18 @@ const remove = defineCommand({
1396
1416
  ...connection
1397
1417
  },
1398
1418
  async run({ args }) {
1399
- const dropDb = Boolean(args["drop-database"]);
1419
+ const app = previewName(args.app ?? await appName(resolveAppDir()), args.preview);
1420
+ const dropDb = Boolean(args["drop-database"]) || app.includes("--");
1400
1421
  if (!args.yes) {
1401
1422
  const ok = await p.confirm({
1402
- message: `Delete ${args.app}${dropDb ? " and ALL its data" : " (data is kept, the name stays yours)"}?`,
1423
+ message: `Delete ${app}${dropDb ? " and ALL its data" : " (data is kept, the name stays yours)"}${app.includes("--") ? "" : ", and all its previews"}?`,
1403
1424
  initialValue: false
1404
1425
  });
1405
1426
  if (p.isCancel(ok) || !ok) return p.cancel("Cancelled");
1406
1427
  }
1407
- await api(`/v1/apps/${args.app}?dropDatabase=${dropDb}`, args, { method: "DELETE" });
1408
- console.log(`Deleted ${args.app}${dropDb ? " and its database" : ""}`);
1428
+ const { previews = [] } = await (await api(`/v1/apps/${app}?dropDatabase=${dropDb}`, args, { method: "DELETE" })).json();
1429
+ console.log(`Deleted ${app}${dropDb ? " and its database" : ""}`);
1430
+ if (previews.length) console.log(`Also deleted its previews: ${previews.join(", ")}`);
1409
1431
  }
1410
1432
  });
1411
1433
  const LEVEL_COLORS = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wervt/cli",
3
- "version": "0.2.18",
3
+ "version": "0.2.19",
4
4
  "description": "Deploy and manage apps on wervt.",
5
5
  "keywords": [
6
6
  "agents",
package/skill/SKILL.md CHANGED
@@ -123,7 +123,9 @@ git push -u origin main
123
123
  ```
124
124
 
125
125
  The pipe hands the deploy token straight to GitHub; it never appears in the output. A deploy token
126
- can only deploy that one app. Set the secret and variable **before** the first push, or the first
126
+ can only deploy that one app and its previews: `.github/workflows/preview.yml` deploys every pull
127
+ request to `<name>--pr-<number>` (own empty database, the app's access and env plus its preview
128
+ env, `wervt env <name> --preview --set …`) and deletes it when the pull request closes. Set the secret and variable **before** the first push, or the first
127
129
  workflow run fails. Then `gh run watch` and check `pnpm exec wervt releases <name>`: the new
128
130
  release lists the commit.
129
131