nimblybase 0.1.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.
- package/README.md +222 -0
- package/dist/index.js +4165 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# nimblybase
|
|
2
|
+
|
|
3
|
+
The NimblyBase command line. Projects, keys and backends from a terminal.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx nimblybase login
|
|
7
|
+
npx nimblybase create "My App"
|
|
8
|
+
npx nimblybase keys create "local dev"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Install it properly if you use it often:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g nimblybase
|
|
15
|
+
nimbly --help
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Signing in
|
|
19
|
+
|
|
20
|
+
Run:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
nimbly login
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The CLI opens your browser, where you choose the organization and approve
|
|
27
|
+
the requested permissions. The resulting grant is stored in your login
|
|
28
|
+
keychain on macOS, and otherwise in
|
|
29
|
+
`~/.config/nimblybase/credentials.json` with permissions `0600`. `nimbly
|
|
30
|
+
login` always says which one it used.
|
|
31
|
+
|
|
32
|
+
For a machine without a browser, create an access token in the dashboard
|
|
33
|
+
under **Access tokens** and run `nimbly login --token <token>`. Omitting the
|
|
34
|
+
value prompts without echoing it.
|
|
35
|
+
|
|
36
|
+
In CI, set `NIMBLYBASE_TOKEN` instead. It takes precedence over anything
|
|
37
|
+
stored and is never written to disk.
|
|
38
|
+
|
|
39
|
+
## Linking a directory
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
nimbly link my-app
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Writes `nimblybase.json`, which records the project id and slug and **no
|
|
46
|
+
credentials**. Commit it: a teammate cloning the repo gets the same target
|
|
47
|
+
without being told a UUID. Commands run anywhere beneath it use that project
|
|
48
|
+
unless you name another with `-p`.
|
|
49
|
+
|
|
50
|
+
## Scripting
|
|
51
|
+
|
|
52
|
+
Every command takes `--json`. In JSON mode stdout carries the document and
|
|
53
|
+
nothing else — progress, warnings and errors all go to stderr, including a
|
|
54
|
+
machine-readable error document.
|
|
55
|
+
|
|
56
|
+
Exit codes are stable:
|
|
57
|
+
|
|
58
|
+
| code | meaning |
|
|
59
|
+
|---|---|
|
|
60
|
+
| 0 | success |
|
|
61
|
+
| 1 | failed |
|
|
62
|
+
| 2 | bad arguments |
|
|
63
|
+
| 3 | not signed in, or the token is no longer valid |
|
|
64
|
+
| 4 | not found |
|
|
65
|
+
| 5 | refused by permissions |
|
|
66
|
+
| 6 | the API could not be reached |
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
nimbly projects --json | jq -r '.projects[] | select(.status == "active") | .slug'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Opening a table to your app
|
|
73
|
+
|
|
74
|
+
The key that ships in a browser — the anon key — can do **nothing** until a
|
|
75
|
+
policy says otherwise. That is the design, not a gap: the alternative is a
|
|
76
|
+
public key that runs arbitrary SQL.
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
nimbly policies # what is open, and to whom
|
|
80
|
+
nimbly policies allow posts select --using true # let anyone read posts
|
|
81
|
+
nimbly policies allow posts select --using '{"col":"published","eq":true}'
|
|
82
|
+
nimbly policies revoke 3
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
A table absent from `nimbly policies` is closed entirely — which is almost
|
|
86
|
+
always the answer to "why does my app get nothing back".
|
|
87
|
+
|
|
88
|
+
An expression is data, not SQL. `{"col":"published","eq":true}` means
|
|
89
|
+
published rows; `{"and":[…]}` and `{"or":[…]}` combine them; and
|
|
90
|
+
`{"col":"owner_id","eq":{"ctx":"userId"}}` means rows belonging to the
|
|
91
|
+
signed-in end user — which matches **nothing** for an anonymous caller, so it
|
|
92
|
+
fails closed rather than open.
|
|
93
|
+
|
|
94
|
+
`select`, `update` and `delete` need `--using` (which rows may be touched).
|
|
95
|
+
`insert` and `update` need `--check` (which rows may be written).
|
|
96
|
+
|
|
97
|
+
## Edge functions
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
nimbly functions deploy ./webhook.js
|
|
101
|
+
nimbly functions
|
|
102
|
+
nimbly functions delete webhook
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
A function is a standard Worker module — `export default { async fetch(request, env) { … } }` —
|
|
106
|
+
published to `https://<ref>.<host>/fn/<name>`.
|
|
107
|
+
|
|
108
|
+
**The URL is public.** No NimblyBase key is required to call it, because a
|
|
109
|
+
webhook handler that demanded one could not receive a webhook. Check a
|
|
110
|
+
signature or a shared secret inside your own code.
|
|
111
|
+
|
|
112
|
+
It receives **this project's own resources** and nothing else: `env.DB`,
|
|
113
|
+
`env.FILES`, `env.KV`, and `env.VECTORS` / `env.AI` where the project has
|
|
114
|
+
them. It cannot reach another project's anything, and it does not receive
|
|
115
|
+
the platform-wide bindings our own Worker carries.
|
|
116
|
+
|
|
117
|
+
## When something is broken
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
nimbly diagnose
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Checks, in the order things actually break: is the project serving, does it
|
|
124
|
+
have keys, does the database have tables, does any row policy exist, and what
|
|
125
|
+
has actually been failing in the last day. Prints one sentence, then the
|
|
126
|
+
findings that earned it. Key use is inferred from request logs rather than a
|
|
127
|
+
control-plane timestamp that the edge cannot update.
|
|
128
|
+
|
|
129
|
+
The commonest answer by a distance is that a table has no policy — which
|
|
130
|
+
makes an anon key get a 403 rather than an empty list.
|
|
131
|
+
|
|
132
|
+
## Reading as your app reads
|
|
133
|
+
|
|
134
|
+
`nimbly sql` uses a service key and bypasses policies. `nimbly rows` goes
|
|
135
|
+
through the row API, so it sees what an app sees — which is the only way to
|
|
136
|
+
check a policy actually works.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
nimbly rows posts --as anon
|
|
140
|
+
nimbly rows posts --as anon --where published=eq.true --order created_at.desc
|
|
141
|
+
nimbly rows posts --as authenticated --as-user u-42
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Rows back means the app works. A policy error means it is locked out, and the
|
|
145
|
+
message says which role and which operation.
|
|
146
|
+
|
|
147
|
+
`--where` is repeatable and takes `<column>=<op>.<value>` — `eq`, `neq`, `gt`,
|
|
148
|
+
`gte`, `lt`, `lte`, `like`, `in`, `is`. Values never go into a string you have
|
|
149
|
+
to quote.
|
|
150
|
+
|
|
151
|
+
## Logs
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
nimbly logs # the last hour
|
|
155
|
+
nimbly logs --level error # only failures
|
|
156
|
+
nimbly logs --since 24h --route /v1/sql
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
One line per request: status, method, route, duration, rows read. A failed
|
|
160
|
+
SQL statement is printed underneath its own line, because when it is there it
|
|
161
|
+
is the only thing you want to read.
|
|
162
|
+
|
|
163
|
+
Newest **last**, so the thing you just did ends up next to your prompt.
|
|
164
|
+
|
|
165
|
+
Logs are readable while a project is paused — "why did it stop working" is a
|
|
166
|
+
question asked about things that stopped working. They are kept for three
|
|
167
|
+
months, and under heavy load rows are sampled per project; when that happens
|
|
168
|
+
the CLI says so rather than quietly under-reporting.
|
|
169
|
+
|
|
170
|
+
Never recorded: bound parameters, request or response bodies, credentials, or
|
|
171
|
+
a storage object key in the route column. The SQL statement is recorded only
|
|
172
|
+
when it **failed** — a working application should not accumulate a
|
|
173
|
+
three-month copy of its own query history.
|
|
174
|
+
|
|
175
|
+
## Connecting an agent
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
nimbly mcp claude --with-token
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Prints the exact command or config block for Claude Code, Cursor, VS Code, or
|
|
182
|
+
raw MCP JSON. Without `--with-token` it emits a placeholder, because this
|
|
183
|
+
output is the kind of thing people paste into issues.
|
|
184
|
+
|
|
185
|
+
## Environment
|
|
186
|
+
|
|
187
|
+
| variable | effect |
|
|
188
|
+
|---|---|
|
|
189
|
+
| `NIMBLYBASE_TOKEN` | Use this token instead of the stored one |
|
|
190
|
+
| `NIMBLYBASE_API_URL` | Point at a different API |
|
|
191
|
+
| `NIMBLYBASE_NO_KEYCHAIN` | Set to `1` to always use the credentials file |
|
|
192
|
+
| `NO_COLOR` | Disable colour |
|
|
193
|
+
|
|
194
|
+
## The database
|
|
195
|
+
|
|
196
|
+
The schema is **declared**, not migrated by hand. You write the shape you
|
|
197
|
+
want; the difference is computed and only the difference runs — which is what
|
|
198
|
+
makes `db push` safe to run twice.
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
nimbly db pull # write the live schema to schema.json
|
|
202
|
+
$EDITOR schema.json
|
|
203
|
+
nimbly db status # what push would change, changing nothing
|
|
204
|
+
nimbly db push # plans, prints the statements, asks, then applies
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`db push` **always plans first**, even with `--yes`. Nothing is applied that
|
|
208
|
+
has not been printed. A change that drops a table or column additionally
|
|
209
|
+
needs `--allow-destructive`; `--yes` on its own is consent to run the
|
|
210
|
+
migration, not consent to lose data.
|
|
211
|
+
|
|
212
|
+
A plan that cannot be carried out completely is refused whole — never applied
|
|
213
|
+
half way.
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
nimbly sql "select * from notes where id = ?" --param 7
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
`--param` is repeatable and fills the `?` placeholders in order. Values never
|
|
220
|
+
go into the statement string: a CLI whose only option is to paste them in
|
|
221
|
+
teaches everybody — and every agent reading a shell history — to write
|
|
222
|
+
injectable SQL.
|