naro-cli 0.22.0 → 0.24.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 CHANGED
@@ -23,6 +23,13 @@ asks before opening a dotenv file to fill what is missing. Decline and it
23
23
  prints the `naro env add` commands instead. With `--yes`, `--json` or outside
24
24
  a TTY it never asks — it just lists what is missing and deploys.
25
25
 
26
+ When those names give away a service you are already running, the deploy says
27
+ so instead of leaving you with a list of names. An app that talks to an
28
+ existing Supabase project prints `Supabase — in that project's dashboard:` and
29
+ the screen each missing value is on, so moving the app here is a copy from one
30
+ tab to another. naro never calls Supabase: the values arrive like any other
31
+ env var, from `.env.local` once you agree or from `naro env add`.
32
+
26
33
  Values you register are encrypted at rest, and `naro env pull` /
27
34
  `naro env list --reveal` can read them back — your account credentials are
28
35
  effectively your env credentials.
@@ -220,6 +227,28 @@ naro realtime tables add <table>… Publish tables' changes (within about 10 se
220
227
  naro realtime tables remove <table>… [--yes]
221
228
  Stop publishing tables' changes (asks first)
222
229
 
230
+ naro functions [list] Naro Functions: name, version, verify_jwt, status and URL of each function
231
+ naro functions new <name> Write naro/functions/<name>/index.ts, a handler to start from
232
+ naro functions deploy [name…] [--no-verify-jwt] [--import-map <file>] [--skip-check]
233
+ Bundle on this machine (Node.js 22 or later), check that it starts, upload;
234
+ every function in the folder when no name is given
235
+ naro functions versions <name> Its stored versions, newest first
236
+ naro functions rollback <name> [<version>]
237
+ Put an earlier version live again (the one before the live one by default)
238
+ naro functions delete <name> Delete it: its URL stops working (asks first; --yes to skip)
239
+ naro functions logs <name> [--level <l>] [--follow]
240
+ Its newest log lines
241
+ naro functions secrets [list] The project's function secrets: names and digests, never values
242
+ naro functions secrets set <NAME> Set one (value from a hidden prompt or stdin), then sync the functions
243
+ (--no-sync leaves them to the control plane's sweep)
244
+ naro functions secrets import <file>
245
+ Set a dotenv file's lines (asks first; --yes in CI)
246
+ naro functions secrets unset <NAME>…
247
+ Remove secrets (asks first)
248
+ naro functions secrets sync [--registry]
249
+ Upload out-of-date functions again until none is left; --registry also rewrites
250
+ the function list in the project's database (after naro db restore)
251
+
223
252
  naro promote <deployment-id> [--to <environment>] Publish a build to production, or to an environment (0.20.0); says rebuild or reupload first, then asks
224
253
  naro rollback [deployment-id] Back to the previous production build
225
254
  ```
@@ -855,6 +884,35 @@ An `--update-check` you give replaces the default: without
855
884
 
856
885
  ## Release notes
857
886
 
887
+ ### 0.24.0
888
+
889
+ - `naro deploy` names the service behind the env vars it is missing. Names that
890
+ are `SUPABASE_*` under any framework prefix (`NEXT_PUBLIC_`, `VITE_`,
891
+ `EXPO_PUBLIC_`, …) print `Supabase — in that project's dashboard:` beneath
892
+ the missing-keys line, then only the screens a missing value is actually on —
893
+ `the project URL — the Connect dialog at the top of the page` for a name
894
+ ending `_URL`, `the keys — Settings > API Keys` for one ending `_KEY`. A
895
+ `SUPABASE_*` name neither screen holds (`SUPABASE_ACCESS_TOKEN` is made on
896
+ the account, not in a project; `SUPABASE_DB_PASSWORD`, `SUPABASE_PROJECT_REF`
897
+ and `SUPABASE_JWT_SECRET` are elsewhere) gets no hint at all rather than a
898
+ screen it is not on. When other keys are missing too the line names only the
899
+ ones it placed. Nothing is sent to Supabase and no token is stored; the
900
+ values still come from `.env.local` with your consent or from
901
+ `naro env add`.
902
+ - `naro realtime [status]` ends with the project's month of Realtime, across its environments: `This month (UTC, all environments): <n> messages · est. $<x.xx>`, or `This month (UTC): not metered yet` before the meter's first run (and from a control plane older than this). When an operator caps the project's monthly messages it adds `⚠ This project has used <p>% of its monthly realtime message limit (<limit>).` from 80%, and `⚠ This project has used its realtime messages for this month. Realtime resumes on the 1st at 00:00 UTC.` once new connections are refused. `--json` carries the same as `realtime.usage`.
903
+ - naro-mcp 0.23.0 goes out with it (no tool changes).
904
+
905
+ ### 0.23.0
906
+
907
+ 0.22.0 went out on 2026-10-31 without these.
908
+
909
+ - `naro functions` — Naro Functions (early access; the control plane answers `FUNCTIONS_DISABLED` until it is switched on). `new` writes a function that imports `withNaro` from `naro-js/functions` (naro-js 0.7.0). `deploy` bundles on this machine with esbuild (Node.js 22 or later; `npm:`, `jsr:` and import maps from `deno.json`, `node:` modules as wrangler resolves them, URL imports refused), boots the bundle in workerd (`--skip-check` to skip) with each project secret's name set to the text `naro-boot-check-placeholder`, never its value, uploads it and puts it live; without a name, every function in `naro/functions` (or `--dir`). `list`, `versions`, `rollback <name> [<version>]`, `delete`, `logs [--follow]`.
910
+ - `naro functions secrets set <NAME>` reads the value from stdin or a hidden prompt, never argv; `secrets import <file>` previews the names and each value's size in bytes, never the value; `secrets unset`; each syncs the live functions until none is left (`--no-sync` to leave it to the control plane). `secrets sync [--registry]` finishes a stopped sync and, with `--registry`, rewrites the function list after `naro db restore`. A sync makes at most 110 calls.
911
+ - `naro backend keys rotate` reads the function list before it asks (production's key only: functions are not on an environment's backend, so `--env <name>` reads none): with live functions, the question says they pick up the new key within minutes, and the functions are synced after the rotation (a stop is a warning, not a failure; with `--json`, `functions.error` says why it stopped).
912
+ - naro-cli now depends on esbuild, miniflare, unenv and @cloudflare/unenv-preset directly, at the versions its wrangler pins.
913
+ - Every request names this CLI in an `X-Naro-Client` header (`naro-cli/0.23.0`; naro-mcp 0.22.0 sends `naro-mcp/0.22.0`). Once the operator turns the check on (it waits for these versions to be on npm), the control plane refuses, on a project that has environments, a change to its data sent with a token, no `?environment=` and no such header, with `400 ENVIRONMENT_REQUIRED` — the `db` and `migration` routes, and the backend's keys, sign-in, users, policies, Storage and Realtime, when the call is not a read or reveals a key (turning the backend on or off is not one of them): 0.21.0 and earlier drop `--env` without a word, and their `naro db query "drop table t" --env qa` would have changed production. 0.22.0 understands `--env` but sends no header, so it is refused too on such a project, `--env production` included (it sends no parameter for production): update. Other reads are not refused; scripts that call the API with a token add `?environment=production`.
914
+ - naro-mcp 0.22.0 goes out with it and adds the `functions` tools (see its README). It needs this naro-cli: 0.22.0 and earlier have no `deployFunctions`.
915
+
858
916
  ### 0.22.0
859
917
 
860
918
  0.21.0 went out without this.
package/dist/args.d.ts ADDED
@@ -0,0 +1,238 @@
1
+ export interface GlobalFlags {
2
+ json: boolean;
3
+ yes: boolean;
4
+ debug: boolean;
5
+ help: boolean;
6
+ version: boolean;
7
+ prod: boolean;
8
+ follow: boolean;
9
+ reveal: boolean;
10
+ /**
11
+ * Optional, unlike the booleans above: callers that build flags by hand
12
+ * (tests, embedders) predate it and must keep compiling.
13
+ */
14
+ wait?: boolean | undefined;
15
+ /**
16
+ * `naro domains add --no-www`: register an apex on its own instead of the
17
+ * apex/www pair the dashboard creates by default.
18
+ */
19
+ noWww?: boolean | undefined;
20
+ token?: string | undefined;
21
+ project?: string | undefined;
22
+ team?: string | undefined;
23
+ cwd?: string | undefined;
24
+ name?: string | undefined;
25
+ root?: string | undefined;
26
+ branch?: string | undefined;
27
+ type?: string | undefined;
28
+ env?: string | undefined;
29
+ level?: string | undefined;
30
+ /** `naro insights --metric inp`: the metric of the sections; the server checks it. */
31
+ metric?: string | undefined;
32
+ /** `naro insights --range 30d`: how far back; the server checks it. */
33
+ range?: string | undefined;
34
+ /** `naro usage --month 2026-09`: a UTC calendar month; the server checks it. */
35
+ month?: string | undefined;
36
+ /** `naro insights --route '/posts/[id]'`: the paths opened under one route. */
37
+ route?: string | undefined;
38
+ /**
39
+ * `naro analytics` and `naro insights` narrow a report by these dimensions
40
+ * (spec 2026-10-08 §5); one value each, ANDed, checked by the server.
41
+ * `naro insights` has no referrer and refuses `--referrer`.
42
+ */
43
+ path?: string | undefined;
44
+ referrer?: string | undefined;
45
+ country?: string | undefined;
46
+ device?: string | undefined;
47
+ browser?: string | undefined;
48
+ os?: string | undefined;
49
+ /** `naro db query --file <path>`: read the SQL from a file instead of argv. */
50
+ file?: string | undefined;
51
+ /** `naro db push --dry-run`: list pending migrations without applying. */
52
+ dryRun?: boolean | undefined;
53
+ /** Output path (`naro gen types --output`). Input files use --file. */
54
+ output?: string | undefined;
55
+ /** `naro gen types --lang typescript`: the one language, and the default. */
56
+ lang?: string | undefined;
57
+ /** Migrations directory (`--dir`), relative to the cwd. */
58
+ dir?: string | undefined;
59
+ /** `naro db lint --strict`: a warning fails the run too, not only an error. */
60
+ strict?: boolean | undefined;
61
+ /** `naro db dump --schema-only`: CREATE statements, no rows. */
62
+ schemaOnly?: boolean | undefined;
63
+ /** `naro db dump --data-only`: rows, no CREATE statements. */
64
+ dataOnly?: boolean | undefined;
65
+ /**
66
+ * `naro db dump --table a,b`. A repeated flag keeps only its last value, so
67
+ * this is a comma list — split it with `listFlag`.
68
+ */
69
+ table?: string | undefined;
70
+ /** `naro db restore --timestamp`: RFC 3339 with a timezone, or Unix seconds. */
71
+ timestamp?: string | undefined;
72
+ /** `naro db restore --bookmark`: a Time Travel bookmark. */
73
+ bookmark?: string | undefined;
74
+ /**
75
+ * `naro migration repair --status applied|reverted`: which way the ledger
76
+ * row is wrong. A string, not two boolean flags, so `--status` can be
77
+ * missing (the command refuses to guess) rather than silently defaulting.
78
+ */
79
+ status?: string | undefined;
80
+ /** `naro backend keys rotate --anon`: replace the anon key. */
81
+ anon?: boolean | undefined;
82
+ /** `naro backend keys rotate --service`: replace the service key. */
83
+ service?: boolean | undefined;
84
+ /**
85
+ * `naro policy set <table> --select <rule>` and its three siblings. Strings,
86
+ * so the command can name the flag whose rule it does not know.
87
+ */
88
+ selectRule?: string | undefined;
89
+ insertRule?: string | undefined;
90
+ updateRule?: string | undefined;
91
+ deleteRule?: string | undefined;
92
+ /** `naro policy set --owner <column>`: the column `owner` compares with the user id. */
93
+ ownerColumn?: string | undefined;
94
+ /**
95
+ * `naro db table create|add-column --column <spec>`. The one flag that
96
+ * repeats: every value, in order (spec 2026-09-24 P2-4 §9.2).
97
+ */
98
+ columns?: string[] | undefined;
99
+ /** `naro db table create --if-not-exists`: leave an existing table alone. */
100
+ ifNotExists?: boolean | undefined;
101
+ /** `naro db index create --unique`. */
102
+ unique?: boolean | undefined;
103
+ /** `naro db table|index … --no-write`: apply, but write no migration file. */
104
+ noWrite?: boolean | undefined;
105
+ /**
106
+ * `naro policy set <table> --select-when '<filter>'` and its siblings
107
+ * (P2-2): a condition in Supabase's filter syntax. `--insert-when` is
108
+ * insert's check, `--update-when` update's using, `--update-check` its
109
+ * check.
110
+ */
111
+ selectWhen?: string | undefined;
112
+ insertWhen?: string | undefined;
113
+ updateWhen?: string | undefined;
114
+ updateCheck?: string | undefined;
115
+ deleteWhen?: string | undefined;
116
+ /** `naro policy set --signed-in`: the conditions given need a signed-in user. */
117
+ signedIn?: boolean | undefined;
118
+ /** `naro policy set --from-file <path>`: the whole policy as JSON. */
119
+ fromFile?: string | undefined;
120
+ /**
121
+ * `naro policy create --allow-unindexed` (P2-7 적대적 리뷰 반영): accept a
122
+ * correlated subquery no index serves, which the control plane otherwise
123
+ * refuses — every run of it reads its whole table.
124
+ */
125
+ allowUnindexed?: boolean | undefined;
126
+ /** `naro backend auth email set --provider resend` (P2-6). */
127
+ provider?: string | undefined;
128
+ /** `naro backend auth email set --from "App <no-reply@example.com>"`. */
129
+ from?: string | undefined;
130
+ /** `naro backend auth oauth set <provider> --client-id <id>`. */
131
+ clientId?: string | undefined;
132
+ /**
133
+ * `--api-key-stdin` / `--client-secret-stdin`: the secret comes from stdin
134
+ * (a pipe, or a hidden prompt in a terminal) — never from argv, where it
135
+ * would land in shell history.
136
+ */
137
+ apiKeyStdin?: boolean | undefined;
138
+ clientSecretStdin?: boolean | undefined;
139
+ /** `naro backend users create --username <name>` (spec 2026-09-26 §2.2). */
140
+ username?: string | undefined;
141
+ /** `naro backend users create --email <address>`. */
142
+ email?: string | undefined;
143
+ /**
144
+ * `naro backend users create --password <password>`: allowed, unlike the
145
+ * other secrets, but it lands in shell history, so the command warns;
146
+ * `--password-stdin` is the way that does not.
147
+ */
148
+ password?: string | undefined;
149
+ passwordStdin?: boolean | undefined;
150
+ /** `naro backend auth password --min-length <n>` (spec 2026-09-26 §2.4). */
151
+ minLength?: string | undefined;
152
+ /** `naro storage bucket create|update --public`: anyone with the URL may download its objects. */
153
+ public?: boolean | undefined;
154
+ /** `naro storage bucket update --private`: only the policies decide again. */
155
+ private?: boolean | undefined;
156
+ /** `naro storage bucket create|update --file-size-limit <size>`: bytes, 5MB or 5MiB; `none` clears it. */
157
+ fileSizeLimit?: string | undefined;
158
+ /** `naro storage bucket create|update --allowed-mime-types <t,…>`: a comma list; `any` clears it. */
159
+ allowedMimeTypes?: string | undefined;
160
+ /** `naro storage bucket remove --empty`: delete the bucket's objects first. */
161
+ empty?: boolean | undefined;
162
+ /** `naro storage ls|rm --recursive` (`-r`): everything under a folder. */
163
+ recursive?: boolean | undefined;
164
+ /**
165
+ * `naro storage ls --search <text>`: the names below the prefix that start
166
+ * with it, ASCII case ignored (Storage 3-1g); the worker checks it.
167
+ */
168
+ search?: string | undefined;
169
+ /**
170
+ * `naro storage cp --upsert`: replace an object that is there, in an
171
+ * upload or in a copy inside Storage. `naro storage mv` refuses it.
172
+ */
173
+ upsert?: boolean | undefined;
174
+ /**
175
+ * `naro storage cp --content-type <t>`: an upload's type; by default from
176
+ * the extension. A copy inside Storage keeps the object's own, and
177
+ * `naro storage mv` takes none: both refuse the flag.
178
+ */
179
+ contentType?: string | undefined;
180
+ /**
181
+ * `naro storage cp --cache-control <seconds>`: how long a browser may keep
182
+ * an upload. A copy inside Storage keeps the object's own, and
183
+ * `naro storage mv` takes none: both refuse the flag.
184
+ */
185
+ cacheControl?: string | undefined;
186
+ /**
187
+ * `naro environments set --no-branch`: no branch deploys to the environment
188
+ * any more. Not with `--branch`; the command says so.
189
+ */
190
+ noBranch?: boolean | undefined;
191
+ /**
192
+ * `naro environments create --copy-env preview|production|none`: where the
193
+ * new environment's variables come from. Strings, so the command can name
194
+ * the flag whose value it does not know.
195
+ */
196
+ copyEnv?: string | undefined;
197
+ /** `naro environments create --database schema|empty`: what the new environment's database starts with. */
198
+ database?: string | undefined;
199
+ /** `naro environments set --protection on|off`: who may open the environment. */
200
+ protection?: string | undefined;
201
+ /** `naro functions deploy --no-verify-jwt`: the version takes calls without a project JWT (wins over function.json). */
202
+ noVerifyJwt?: boolean | undefined;
203
+ /** `naro functions deploy --skip-check`: upload without booting the bundle in workerd first. */
204
+ skipCheck?: boolean | undefined;
205
+ /** `naro functions deploy --import-map <file>`: the import map for functions whose folder has none. */
206
+ importMap?: string | undefined;
207
+ /** `naro functions secrets set|import|unset --no-sync`, `naro backend keys rotate --no-sync`: leave the functions to the sweep. */
208
+ noSync?: boolean | undefined;
209
+ /** `naro functions secrets sync --registry`: write the function list in the project's database again too. */
210
+ registry?: boolean | undefined;
211
+ /**
212
+ * `naro promote <id> --to <environment>`: where the deployment goes —
213
+ * `production` or an environment's slug. A string, so the command can refuse
214
+ * an empty one or `preview` before it sends anything.
215
+ */
216
+ to?: string | undefined;
217
+ }
218
+ export interface ParsedArgs {
219
+ command: string | undefined;
220
+ /** Positional arguments after the command (sub-commands, ids, keys...). */
221
+ positionals: string[];
222
+ flags: GlobalFlags;
223
+ /** Flags the parser did not recognize, e.g. ["--frod"]. */
224
+ unknown: string[];
225
+ }
226
+ /** The message for a secret given in argv, or null when there was none. */
227
+ export declare function secretFlagProblem(unknown: readonly string[]): string | null;
228
+ export declare const SECRETS_ARGV_REFUSAL = "Secrets are read from stdin or a file, never from the command line: pipe the value into naro functions secrets set <NAME>, or put it in a file for naro functions secrets import <file>.";
229
+ /**
230
+ * The refusal for options naro does not know. `naro functions secrets set
231
+ * <NAME>` takes its value on stdin, so an unknown option there may be the
232
+ * value itself (`-----BEGIN …`, `--value=…`): it is refused without being
233
+ * shown. Every other command names the options as before.
234
+ */
235
+ export declare function unknownOptionProblem(parsed: ParsedArgs): string;
236
+ /** A comma-list flag (`--table users, posts`) as its trimmed, non-empty pieces. */
237
+ export declare function listFlag(value: string | undefined): string[];
238
+ export declare function parseArgs(argv: string[]): ParsedArgs;