lakebed 0.0.9 → 0.0.11

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/src/cli.js CHANGED
@@ -1,9 +1,11 @@
1
1
  #!/usr/bin/env node
2
+ import { execFile } from "node:child_process";
2
3
  import { createServer } from "node:http";
3
4
  import { existsSync, realpathSync } from "node:fs";
4
5
  import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
5
6
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
6
7
  import { createInterface } from "node:readline/promises";
8
+ import { promisify } from "node:util";
7
9
  import { fileURLToPath, pathToFileURL } from "node:url";
8
10
  import * as esbuild from "esbuild";
9
11
  import { WebSocketServer } from "ws";
@@ -28,19 +30,21 @@ const packageDir = resolve(dirname(fileURLToPath(import.meta.url)), "..");
28
30
  const packageNodeModules = resolve(packageDir, "node_modules");
29
31
  const sourceNamespace = "lakebed-source";
30
32
  const defaultDeployApiUrl = "https://api.lakebed.app";
33
+ const execFileAsync = promisify(execFile);
31
34
 
32
35
  function usage() {
33
36
  console.log(`lakebed
34
37
 
35
38
  Usage:
36
- lakebed new [name] [--template todo]
37
- lakebed dev <capsule-dir> [--port 3000]
38
- lakebed build <capsule-dir> --target anonymous [--out .lakebed/artifacts/app.json] [--json]
39
+ lakebed new [name] [--template todo] [--no-git]
40
+ lakebed create [name] [--template todo] [--no-git]
41
+ lakebed dev [capsule-dir] [--port 3000]
42
+ lakebed build [capsule-dir] --target anonymous [--out .lakebed/artifacts/app.json] [--json]
39
43
  lakebed deploy [capsule-dir] [--ttl 7d] [--api <url>] [--json]
40
44
  lakebed claim [capsule-dir] [--api <url>] [--json]
41
45
  lakebed anonymous-server [--port 8787] [--public-root-url <url>] [--app-base-domain <domain>]
42
46
  lakebed inspect <deploy-id-or-url> [--api <url>] [--json]
43
- lakebed run-many <capsule-dir> [--count 20] [--base-port 4000]
47
+ lakebed run-many [capsule-dir] [--count 20] [--base-port 4000]
44
48
  lakebed auth as <name>
45
49
  lakebed auth reset
46
50
  lakebed db list [deploy-id-or-url] [--port 3000]
@@ -58,12 +62,27 @@ function readArg(args, name, fallback) {
58
62
  return args[index + 1] ?? fallback;
59
63
  }
60
64
 
65
+ const optionsWithValues = new Set([
66
+ "--api",
67
+ "--app-base-domain",
68
+ "--base-port",
69
+ "--count",
70
+ "--out",
71
+ "--port",
72
+ "--public-root-url",
73
+ "--target",
74
+ "--template",
75
+ "--ttl"
76
+ ]);
77
+
61
78
  function positionals(args) {
62
79
  const values = [];
63
80
  for (let index = 0; index < args.length; index += 1) {
64
81
  const value = args[index];
65
82
  if (value.startsWith("--")) {
66
- index += 1;
83
+ if (optionsWithValues.has(value)) {
84
+ index += 1;
85
+ }
67
86
  continue;
68
87
  }
69
88
 
@@ -88,7 +107,7 @@ function hasFlag(args, name) {
88
107
 
89
108
  function resolveCapsuleDir(value) {
90
109
  if (!value) {
91
- return resolve(root, "examples/todo");
110
+ return root;
92
111
  }
93
112
 
94
113
  return isAbsolute(value) ? value : resolve(root, value);
@@ -827,7 +846,7 @@ async function readResponseJson(response) {
827
846
 
828
847
  async function deployCommand(args) {
829
848
  const [capsuleArg] = positionals(args);
830
- const capsuleDir = capsuleArg ? resolveCapsuleDir(capsuleArg) : root;
849
+ const capsuleDir = resolveCapsuleDir(capsuleArg);
831
850
  const sourceStore = await createMemorySourceStoreFromDirectory(capsuleDir);
832
851
  const serverEnvFileExists = sourceStore.hasFile(SERVER_ENV_FILE);
833
852
  const serverEnv = await readCapsuleServerEnv(sourceStore);
@@ -969,7 +988,7 @@ async function deployCommand(args) {
969
988
 
970
989
  async function claimCommand(args) {
971
990
  const [capsuleArg] = positionals(args);
972
- const capsuleDir = capsuleArg ? resolveCapsuleDir(capsuleArg) : root;
991
+ const capsuleDir = resolveCapsuleDir(capsuleArg);
973
992
  const api = deployApiUrl(args);
974
993
  const metadata = await readDeployMetadata(capsuleDir);
975
994
 
@@ -1149,7 +1168,7 @@ This is a Lakebed capsule. Build the app inside this directory using the Lakebed
1149
1168
  Run locally:
1150
1169
 
1151
1170
  \`\`\`sh
1152
- lakebed dev .
1171
+ lakebed dev
1153
1172
  \`\`\`
1154
1173
 
1155
1174
  Deploy:
@@ -1311,6 +1330,7 @@ pnpm lakebed dev ${name}
1311
1330
  async function newCommand(args) {
1312
1331
  const [nameArg] = positionals(args);
1313
1332
  const template = readArg(args, "--template", "todo");
1333
+ const shouldInitGit = !hasFlag(args, "--no-git");
1314
1334
 
1315
1335
  if (template !== "todo") {
1316
1336
  throw new Error(`Unknown template: ${template}`);
@@ -1334,6 +1354,51 @@ async function newCommand(args) {
1334
1354
  }
1335
1355
 
1336
1356
  console.log(`Created Lakebed capsule at ${targetDir}`);
1357
+ const gitStatus = shouldInitGit ? await initializeGitRepository(targetDir) : "Skipped git setup (--no-git).";
1358
+ console.log(gitStatus);
1359
+ console.log(`
1360
+ Next:
1361
+ cd ${shellQuote(name)}
1362
+ npx lakebed dev
1363
+
1364
+ deploy instantly for free with:
1365
+ npx lakebed deploy`);
1366
+ }
1367
+
1368
+ async function initializeGitRepository(targetDir) {
1369
+ if (await isInsideGitWorkTree(dirname(targetDir))) {
1370
+ return "Skipped git setup because the capsule is inside an existing git repository.";
1371
+ }
1372
+
1373
+ try {
1374
+ await execFileAsync("git", ["init"], { cwd: targetDir });
1375
+ await execFileAsync("git", ["add", "."], { cwd: targetDir });
1376
+ await execFileAsync(
1377
+ "git",
1378
+ ["-c", "user.name=Lakebed", "-c", "user.email=lakebed@example.invalid", "commit", "-m", "Initial Lakebed capsule"],
1379
+ { cwd: targetDir }
1380
+ );
1381
+ return "Initialized git repository and created initial commit.";
1382
+ } catch (error) {
1383
+ return `Skipped git setup: ${error instanceof Error ? error.message : String(error)}`;
1384
+ }
1385
+ }
1386
+
1387
+ async function isInsideGitWorkTree(cwd) {
1388
+ try {
1389
+ const { stdout } = await execFileAsync("git", ["rev-parse", "--is-inside-work-tree"], { cwd });
1390
+ return stdout.trim() === "true";
1391
+ } catch {
1392
+ return false;
1393
+ }
1394
+ }
1395
+
1396
+ function shellQuote(value) {
1397
+ if (/^[A-Za-z0-9_./:-]+$/.test(value)) {
1398
+ return value;
1399
+ }
1400
+
1401
+ return `'${value.replaceAll("'", "'\\''")}'`;
1337
1402
  }
1338
1403
 
1339
1404
  async function promptForCapsuleName() {
@@ -1396,7 +1461,7 @@ async function runMany(args) {
1396
1461
  async function main() {
1397
1462
  const [command, ...args] = process.argv.slice(2);
1398
1463
 
1399
- if (command === "new") {
1464
+ if (command === "new" || command === "create") {
1400
1465
  await newCommand(args);
1401
1466
  return;
1402
1467
  }
package/src/version.js CHANGED
@@ -1 +1 @@
1
- export const LAKEBED_VERSION = "0.0.9";
1
+ export const LAKEBED_VERSION = "0.0.11";