sproutboat 0.4.9 → 0.4.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/README.md +49 -27
- package/SURFACE.md +1 -1
- package/package.json +1 -1
- package/src/main.ts +14 -3
package/README.md
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# sproutboat
|
|
2
2
|
|
|
3
|
-
The CLI for [Sproutboat](https://github.com/baronunread/sproutboat)
|
|
4
|
-
Wrangler-shaped tool
|
|
5
|
-
MIT licensed.
|
|
3
|
+
The CLI for [Sproutboat](https://github.com/baronunread/sproutboat). It is a
|
|
4
|
+
Wrangler-shaped tool that compiles a `fetch` handler to a native binary and
|
|
5
|
+
ships it to any Sproutboat control plane. MIT licensed.
|
|
6
|
+
|
|
7
|
+
Full reference: [sproutboat.com/docs](https://sproutboat.com/docs)
|
|
8
|
+
(plain text for agents: [sproutboat.com/llms.txt](https://sproutboat.com/llms.txt)).
|
|
6
9
|
|
|
7
10
|
```sh
|
|
8
|
-
bunx sproutboat login --api-url https://control.example.com
|
|
11
|
+
bunx sproutboat login --api-url https://control.example.com # one browser approval
|
|
9
12
|
bunx sproutboat init hello
|
|
10
13
|
cd hello
|
|
11
14
|
bunx sproutboat deploy
|
|
@@ -19,7 +22,11 @@ bun add -g sproutboat # then: sproutboat deploy, sproutboat tail, ...
|
|
|
19
22
|
|
|
20
23
|
Want it shorter? Alias it yourself: `alias sprout='sproutboat'`.
|
|
21
24
|
|
|
22
|
-
|
|
25
|
+
The `login` browser step is one-time. It writes a long-lived token to
|
|
26
|
+
`~/.config/sproutboat/credentials.json`, keyed by API URL, so you can hold
|
|
27
|
+
logins for several instances at once. For CI or an agent, skip `login`
|
|
28
|
+
entirely and set `SPROUTBOAT_API_URL` + `SPROUTBOAT_TOKEN` (copy the token out
|
|
29
|
+
of that file).
|
|
23
30
|
|
|
24
31
|
## Commands
|
|
25
32
|
|
|
@@ -27,20 +34,23 @@ For CI, skip `login` and set `SPROUTBOAT_API_URL` + `SPROUTBOAT_TOKEN`.
|
|
|
27
34
|
| --- | --- |
|
|
28
35
|
| `init [name]` | Scaffold `sproutboat.jsonc` + `src/index.js` |
|
|
29
36
|
| `check` | Validate the config and entry point |
|
|
30
|
-
| `build` | Cross-compile the
|
|
31
|
-
| `deploy [--dry-run] [--artifact <dir>]` | Build
|
|
32
|
-
| `login [--api-url <url>] [--token <token>]` | Browser device flow, or store a token |
|
|
33
|
-
| `tail [name]` | Recent logs |
|
|
37
|
+
| `build` | Cross-compile the sprout binary (Porffor + Zig) |
|
|
38
|
+
| `deploy [--dry-run] [--no-wait] [--no-provision] [--artifact <dir>]` | Build, auto-provision id-less storage bindings, upload, wait until the URL serves |
|
|
39
|
+
| `login [--api-url <url>] [--token <token>]` | Browser device flow, or store a token directly |
|
|
40
|
+
| `tail [name] [--sprout]` | Recent request logs; `--sprout` streams the running sprout + broker output |
|
|
34
41
|
| `versions list [name]` | Deployed versions |
|
|
35
42
|
| `rollback <id>` | Activate a previous version |
|
|
36
|
-
| `
|
|
43
|
+
| `secrets [list \| set <NAME> [value] \| rm <NAME>]` | Encrypted project secrets, read as `env.NAME` |
|
|
44
|
+
| `resource [list \| create <kind> <name> \| rename <id> <name> \| delete <id>]` | Account-level KV / D1 / R2 / queue stores |
|
|
45
|
+
| `domains [list \| add <host> \| verify <host> \| rm <host>]` | Attach your own hostname (TXT + A, apex allowed) |
|
|
46
|
+
| `delete --yes` | Delete the project, every version, and its route |
|
|
37
47
|
|
|
38
|
-
|
|
39
|
-
|
|
48
|
+
Run `sproutboat` with no arguments for the grouped list.
|
|
49
|
+
[`SURFACE.md`](SURFACE.md) is the generated inventory of every command and env var.
|
|
40
50
|
|
|
41
51
|
## Config
|
|
42
52
|
|
|
43
|
-
`sproutboat.jsonc
|
|
53
|
+
`sproutboat.jsonc`: the entry point plus Cloudflare-shaped `env.*` bindings.
|
|
44
54
|
|
|
45
55
|
```jsonc
|
|
46
56
|
{
|
|
@@ -50,42 +60,54 @@ you can hold logins for several instances at once.
|
|
|
50
60
|
|
|
51
61
|
"vars": { "SITE": "hi" },
|
|
52
62
|
"secrets": ["API_KEY"],
|
|
53
|
-
"kv_namespaces": ["CACHE"],
|
|
63
|
+
"kv_namespaces": ["CACHE"], // bare name, or { "binding": "CACHE", "id": "kv_..." }
|
|
54
64
|
"d1_databases": ["DB"],
|
|
55
65
|
"r2_buckets": ["UPLOADS"],
|
|
56
66
|
"queues": ["JOBS"],
|
|
57
|
-
"analytics_engine_datasets": ["METRICS"],
|
|
67
|
+
"analytics_engine_datasets": ["METRICS"], // bare name only, no id
|
|
58
68
|
"durable_objects": { "COUNTER": "Counter" },
|
|
59
69
|
"outbound": ["api.example.com"],
|
|
60
70
|
"triggers": { "crons": ["*/5 * * * *"] },
|
|
61
|
-
"assets": { "directory": "public", "binding": "ASSETS" }
|
|
71
|
+
"assets": { "directory": "public", "binding": "ASSETS", "run_sprout_first": ["/api/*"] }
|
|
62
72
|
}
|
|
63
73
|
```
|
|
64
74
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
A bare `"CACHE"` binding is auto-provisioned on `deploy`: the CLI creates an
|
|
76
|
+
account-level resource, writes its id back into `sproutboat.jsonc`, and the
|
|
77
|
+
store then survives redeploys. Pass `--no-provision` to keep it a throwaway
|
|
78
|
+
per-deploy store instead, or `sproutboat resource create` to make one up front
|
|
79
|
+
and share its id across projects.
|
|
80
|
+
|
|
81
|
+
The handler is one `export default { fetch(request) }`, optionally with
|
|
82
|
+
`scheduled(event)` / `queue(batch)` handlers and Durable Object classes above
|
|
83
|
+
it. `env` is a global (not a parameter), and every binding call is synchronous.
|
|
84
|
+
See [`examples/kitchen-sink/`](examples/kitchen-sink) for one app that uses
|
|
85
|
+
every binding.
|
|
69
86
|
|
|
70
87
|
## Requirements
|
|
71
88
|
|
|
72
89
|
- [Bun](https://bun.sh) 1.4+
|
|
73
90
|
|
|
74
91
|
`build` / `deploy` cross-compile the handler to a static `linux-x86_64` binary
|
|
75
|
-
with Porffor and Zig (
|
|
76
|
-
ships a prebuilt uWebSockets
|
|
77
|
-
no root. On Windows, build from WSL.
|
|
92
|
+
with Porffor and Zig (the CLI fetches Zig automatically on first use). The
|
|
93
|
+
package ships a prebuilt uWebSockets and compiles nothing else from source. No
|
|
94
|
+
Docker, no root. On Windows, build from WSL.
|
|
78
95
|
|
|
79
96
|
If that prebuilt is unusable (a `porffor` pin bump before the archive is
|
|
80
97
|
refreshed), the first build falls back to compiling uWebSockets locally, which
|
|
81
98
|
needs `git` and `make` on `PATH`. `SPROUTBOAT_UWS_TARBALL=<archive>` overrides
|
|
82
99
|
the shipped one.
|
|
83
100
|
|
|
84
|
-
## Limits
|
|
101
|
+
## Limits
|
|
85
102
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
103
|
+
Capability profile `http-sync-v0`: one synchronous `fetch` handler, optional
|
|
104
|
+
`scheduled` / `queue` handlers, no streaming, no WebSockets. Binding values are
|
|
105
|
+
text/JSON and travel one at a time over the loopback frame (32 MiB cap);
|
|
106
|
+
large-object R2 is [#56](https://github.com/baronunread/sproutboat/issues/56).
|
|
107
|
+
The sprout upload caps at 16 MiB, assets at 64 MiB / 4096 files. Node
|
|
108
|
+
compatibility is Porffor alpha, so `import`/`require`, `process`, `node:*`, and
|
|
109
|
+
parsing date strings do not work; `sproutboat check` catches most of it. Full
|
|
110
|
+
list at [sproutboat.com/docs](https://sproutboat.com/docs).
|
|
89
111
|
|
|
90
112
|
---
|
|
91
113
|
|
package/SURFACE.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> Generated by `src/surface.test.ts` from `src/surface.ts` + the pinned
|
|
4
4
|
> toolchain constants. Do not edit by hand — run `UPDATE_SURFACE=1 bun test`.
|
|
5
5
|
|
|
6
|
-
**Package:** `sproutboat` 0.4.
|
|
6
|
+
**Package:** `sproutboat` 0.4.11 · runs on Bun (use `bunx`, not `npx`)
|
|
7
7
|
|
|
8
8
|
## Commands
|
|
9
9
|
|
package/package.json
CHANGED
package/src/main.ts
CHANGED
|
@@ -409,21 +409,32 @@ async function tail(args: string[]) {
|
|
|
409
409
|
process.stdout.write(await responseText(response, "could not read logs"));
|
|
410
410
|
}
|
|
411
411
|
|
|
412
|
-
type DomainView = {
|
|
412
|
+
type DomainView = {
|
|
413
|
+
hostname: string;
|
|
414
|
+
verified: boolean;
|
|
415
|
+
verification: { type: string; name: string; value: string } | null;
|
|
416
|
+
serverAddresses: string[];
|
|
417
|
+
warning?: string;
|
|
418
|
+
};
|
|
413
419
|
function parseDomain(source: string): DomainView | undefined {
|
|
414
420
|
const record = jsonObject(parseJsonValue(source));
|
|
415
421
|
if (!record || !isString(record.hostname) || typeof record.verified !== "boolean") return undefined;
|
|
416
422
|
const v = jsonObject(record.verification ?? null);
|
|
417
423
|
const verification = v && isString(v.type) && isString(v.name) && isString(v.value) ? { type: v.type, name: v.name, value: v.value } : null;
|
|
418
|
-
|
|
424
|
+
const serverAddresses = Array.isArray(record.serverAddresses) ? record.serverAddresses.filter(isString) : [];
|
|
425
|
+
return { hostname: record.hostname, verified: record.verified, verification, serverAddresses, warning: isString(record.warning) ? record.warning : undefined };
|
|
419
426
|
}
|
|
420
427
|
function printDomain(domain: DomainView) {
|
|
421
428
|
const status = domain.verified ? "verified" : "unverified";
|
|
422
429
|
console.log(`${status.padEnd(10)} ${domain.hostname}`);
|
|
423
430
|
if (domain.verification) {
|
|
424
|
-
console.log(
|
|
431
|
+
console.log(" add these DNS records, then run: sproutboat domains verify " + domain.hostname);
|
|
425
432
|
console.log(` ${domain.verification.type} ${domain.verification.name} "${domain.verification.value}"`);
|
|
433
|
+
if (domain.serverAddresses[0]) {
|
|
434
|
+
console.log(` A ${domain.hostname} ${domain.serverAddresses[0]} (point the hostname here, DNS-only / not proxied)`);
|
|
435
|
+
}
|
|
426
436
|
}
|
|
437
|
+
if (domain.warning) console.log(amber(` ! ${domain.warning}`));
|
|
427
438
|
}
|
|
428
439
|
|
|
429
440
|
async function domains(args: string[]) {
|