naro-cli 0.24.0 → 0.26.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
@@ -27,7 +27,7 @@ When those names give away a service you are already running, the deploy says
27
27
  so instead of leaving you with a list of names. An app that talks to an
28
28
  existing Supabase project prints `Supabase — in that project's dashboard:` and
29
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
30
+ tab to another. Naro never calls Supabase: the values arrive like any other
31
31
  env var, from `.env.local` once you agree or from `naro env add`.
32
32
 
33
33
  Values you register are encrypted at rest, and `naro env pull` /
@@ -102,6 +102,8 @@ naro env remove DATABASE_URL The production, preview and all values; an en
102
102
  naro env pull [.env.local] Preview's values by default; --env production, or --env qa for an environment
103
103
  (its own value wins over all; an unknown name fails before anything is written,
104
104
  and so does a value no dotenv line reads back)
105
+ naro supabase [list] The project's Supabase links, per target (connect in the dashboard)
106
+ naro supabase disconnect [target] Remove a target's link, or (no target or all) every link your role may change, with its env vars (asks first)
105
107
  naro env import .env.qa qa Upload every variable in a dotenv file to one target (all by default; asks first,
106
108
  --yes in CI; an unclosed quote, an invalid key, ASSETS or a value over 5 KB
107
109
  stops it before any request, and so does a key a storage binding already uses
@@ -255,7 +257,7 @@ naro rollback [deployment-id] Back to the previous production build
255
257
 
256
258
  `naro domains list` reads the stored status; `naro domains verify` is the one
257
259
  that asks the DNS and Cloudflare again — and registers the domain on the spot
258
- once its CNAME points at naro — so it is what turns a stuck "pending" into the
260
+ once its CNAME points at Naro — so it is what turns a stuck "pending" into the
259
261
  reason it is stuck. It exits non-zero while a domain is not live —
260
262
  with or without `--wait` — so CI can gate on it:
261
263
 
@@ -278,7 +280,7 @@ The check lasts 7 days. `naro domains list` shows open checks with their
278
280
  expiry, and adding the domain again prints the same token.
279
281
 
280
282
  `naro db dump` asks Cloudflare for the dump and streams it straight from
281
- Cloudflare's storage to the file — the bytes never pass through naro. While the
283
+ Cloudflare's storage to the file — the bytes never pass through Naro. While the
282
284
  export runs, Cloudflare holds every other query to the database, so dump a busy
283
285
  production database when a short pause is acceptable. It ends with the bookmark
284
286
  the dump reflects; `naro db restore --bookmark <that>` brings the database back
@@ -337,13 +339,13 @@ naro db lint --strict --json || exit 1
337
339
 
338
340
  `db lint` changes nothing, but it needs **write** access to the database, not
339
341
  read: its two checks (`foreign_key_check`, `quick_check`) are whole-database
340
- scans, and naro classifies those as writes on purpose so a read-only role
342
+ scans, and Naro classifies those as writes on purpose so a read-only role
341
343
  cannot start them. That is also the cost warning — both walk every row that
342
344
  has a foreign key, and `quick_check` walks the file, so on a large database
343
345
  the lint is billed rows-read and can run into the 30-second query limit. Run
344
346
  it in CI on a branch's own data, not on a busy production database.
345
347
 
346
- `naro db table` and `naro db index` change the schema without SQL. naro
348
+ `naro db table` and `naro db index` change the schema without SQL. Naro
347
349
  renders the DDL from checked input — every name quoted, types and defaults
348
350
  from a fixed list — and applies it as one migration, recorded in
349
351
  `d1_migrations` and written to `./migrations` as `NNNN_schema_<op>_<table>.sql`,
@@ -392,7 +394,7 @@ reads `members`. The command names each policy the change breaks and why;
392
394
 
393
395
  SQLite cannot add a PRIMARY KEY, UNIQUE or NOT-NULL-without-default column, or
394
396
  drop a primary key, a unique or indexed column, or a table another table
395
- references; naro refuses those before it tries and says why. It also reads the
397
+ references; Naro refuses those before it tries and says why. It also reads the
396
398
  SQL of your triggers and views, and refuses to drop or rename a table or
397
399
  column one of them uses (it warns when the SQL leaves that open) — drop or
398
400
  recreate the trigger or view with a migration first. Changing a
@@ -443,7 +445,7 @@ are unchanged.
443
445
  `naro backend` is the project's Naro backend: its own D1, email and password
444
446
  sign-in, and a Data API that browser code calls through `naro-js` at the
445
447
  project's URL. It is off until you turn it on, one project at a time:
446
- `naro backend enable` (or the Database page of the dashboard). The anon key
448
+ `naro backend enable` (or Turn on in the Backend section of the project's Settings page in the dashboard). The anon key
447
449
  is public — it identifies the project and grants nothing. The service key
448
450
  skips every policy, so the CLI prints it only for
449
451
  `naro backend keys --reveal` and for a rotation that made a new one; keep it
@@ -484,7 +486,7 @@ message that the worker may still expect the new key — run
484
486
  `naro backend enable`; the CLI prints that hint (JSON `hint`) and exits 1.
485
487
  For a few seconds during a rotation the worker can already refuse the old key.
486
488
 
487
- Sign-in is naro Auth, the project's own (like Supabase Auth). Email and
489
+ Sign-in is Naro Auth, the project's own (like Supabase Auth). Email and
488
490
  password sign-up and sign-in work as soon as the backend is on, with nothing
489
491
  to set up. `naro backend auth` adds the rest with the project's own
490
492
  accounts — Naro runs no shared sender. Sending email (confirmation and
@@ -607,7 +609,7 @@ EXISTS` skips a missing table too, as in Postgres); `COMMENT ON POLICY p ON t
607
609
  IS 'naro:owner <column>'`, which makes `p` the owner rule `naro policy set
608
610
  --owner` writes (any other comment is ignored); and `ALTER TABLE t ENABLE |
609
611
  FORCE | NO FORCE ROW LEVEL SECURITY`, which changes nothing because
610
- row-level security is always on. Before anything runs, naro refuses these with
612
+ row-level security is always on. Before anything runs, Naro refuses these with
611
613
  `400 VALIDATION_FAILED` "Statement <i> of <n>: …":
612
614
 
613
615
  - `ALTER TABLE … DISABLE ROW LEVEL SECURITY` — it is always on; to let
@@ -623,7 +625,7 @@ has no schema "public": write the table name without "public."`
623
625
  or alters the policy's table or a table its subqueries read: `a later
624
626
  statement changes a table, so name the table of every column inside this
625
627
  policy's subqueries (for example members.user_id).` Postgres decides whose
626
- column it is when the policy is created; naro binds it once the file is in,
628
+ column it is when the policy is created; Naro binds it once the file is in,
627
629
  when the later statement may have added that name to the subquery's table.
628
630
  A later statement that changes only other tables — the next table of a file
629
631
  grouped table by table — leaves the policy alone.
@@ -774,7 +776,7 @@ to write — as text, `'true'` would read as false. So is comparing text with
774
776
  `IS DISTINCT FROM`, also through `coalesce` — since the text `'true'` is not
775
777
  `TRUE`: `<> false` would hold for everyone.
776
778
 
777
- Where naro differs from Postgres: no policy for a command is a 403, not zero
779
+ Where Naro differs from Postgres: no policy for a command is a 403, not zero
778
780
  rows; row-level security is always on; roles are only `anon` and
779
781
  `authenticated`, with no `security definer` functions; comparisons follow
780
782
  SQLite (column affinity and collation), and `lower`, `upper` and `ILIKE` fold
@@ -884,6 +886,59 @@ An `--update-check` you give replaces the default: without
884
886
 
885
887
  ## Release notes
886
888
 
889
+ ### 0.26.0
890
+
891
+ - `naro dashboard [<capability>]` prints the dashboard URL for what the CLI
892
+ leaves there on purpose (payments, the GitHub App, Supabase sign-in, saved
893
+ queries).
894
+ - `naro bindings` is gone, with the dashboard's hosting Storage page and its
895
+ routes: a project's storage is its Naro backend now — files in Storage,
896
+ SQL in the database (bound to the app as `env.DB`). Older versions answer
897
+ `NOT_FOUND` on `naro bindings`, and so does `naro env import` past 100
898
+ variables, which read the bindings first; this one reads the project only.
899
+ - naro-mcp 0.25.0 goes out with it: `dashboard_link` and server instructions
900
+ that point at the dashboard for what no tool does; `list_bindings` and
901
+ `add_binding` are gone. It imports from this release, so publish naro-cli
902
+ first.
903
+
904
+ ### 0.25.0
905
+
906
+ Everything the dashboard does, the CLI now does too, except what needs a
907
+ browser or your own folder (the capability registry in
908
+ `packages/core/src/capabilities.ts` says which and why).
909
+
910
+ - Teams: `naro teams`, `naro team create | set | delete`, `naro team members`
911
+ (`set`, `remove`) and `naro team invites` (`create`, `revoke`). Deleting a
912
+ team asks you to type its slug, or `--team` with `--yes` in CI.
913
+ - Projects: `naro project set` (name, subdomain), `naro project check
914
+ <subdomain>`, `naro project access` (`grant`, `revoke`) and `naro project
915
+ delete`, which asks you to type the project's name (`--yes` only with
916
+ `--project`).
917
+ - The edge: `naro firewall` (`add`, `enable`, `disable`, `remove`), `naro flags`
918
+ (`add`, `on`, `off`, `remove`) and `naro bindings` (`add`, `remove` — removing
919
+ deletes the R2 bucket, KV namespace or D1 database with its data, and asks).
920
+ - DNS: `naro dns` with `add`, `remove`, `check`, `mail`, `scan`, `import` and
921
+ `records` (`add`, `update`, `remove`).
922
+ - Readouts: `naro billing` and `naro observability`. `naro deployments create`
923
+ deploys a branch from Git (`--prod` for production; `--env production` is
924
+ refused).
925
+ - Data: `naro storage sign` (a download link without a key), `naro functions
926
+ update --verify-jwt <on|off>`, `naro functions invoke` (method, `--data`,
927
+ the first 64 KiB of the answer, 120 seconds), `naro policy rules` and
928
+ `naro backend signing-key rotate`.
929
+ - `naro supabase [list]` shows the Supabase project the dashboard connected
930
+ per target; `naro supabase disconnect [target]` removes a link with the env
931
+ vars it set (asks first). With no target, or `all`, it removes every link
932
+ your role may change and names the ones it could not.
933
+ - naro-mcp 0.24.0 goes out with it: tools for teams, DNS, the firewall, flags,
934
+ bindings, the backend and its sign-in settings, Realtime, Storage bucket
935
+ details, upload URLs and moves, policies and policy rules, `lint_database`,
936
+ `pull_database_schema`, billing, Observability, `check_promotion`,
937
+ `deploy_from_git` and the Supabase links. Destructive tools say so in their
938
+ description and set `destructiveHint`; tools that answer text someone else
939
+ typed wrap it as untrusted. It imports from this release, so publish
940
+ naro-cli first.
941
+
887
942
  ### 0.24.0
888
943
 
889
944
  - `naro deploy` names the service behind the env vars it is missing. Names that
@@ -920,7 +975,7 @@ An `--update-check` you give replaces the default: without
920
975
  - `naro deploy --env <name>` builds with the values the control plane
921
976
  chose for the environment, over the ones it sent (named environments 3d).
922
977
  The control plane saves what the deploy sends for that environment first,
923
- so the two differ only where naro sets a name itself: for a project with a
978
+ so the two differ only where Naro sets a name itself: for a project with a
924
979
  Naro backend, an environment's build gets `NARO_URL`,
925
980
  `NEXT_PUBLIC_NARO_URL`, `VITE_NARO_URL`, `PUBLIC_NARO_URL` and the four
926
981
  `…_NARO_ANON_KEY` names set to that environment's own address and anon key.
@@ -956,7 +1011,7 @@ An `--update-check` you give replaces the default: without
956
1011
  `naro environments delete` now says it removes the environment's data too.
957
1012
  - `naro deploy --env <name>` no longer asks for `NARO_URL`,
958
1013
  `NEXT_PUBLIC_NARO_URL`, `VITE_NARO_URL`, `PUBLIC_NARO_URL` or the four
959
- `…_NARO_ANON_KEY` names when the project has a Naro backend: naro sets them
1014
+ `…_NARO_ANON_KEY` names when the project has a Naro backend: Naro sets them
960
1015
  for the environment over any value, so a typed one only lost. It reads the
961
1016
  project's backend once, and only when one of those names is missing
962
1017
  (`▸ naro sets … for qa to its own backend's: not asked for`); a role that
@@ -1156,8 +1211,7 @@ An `--update-check` you give replaces the default: without
1156
1211
  value (`KEY=`) is uploaded like any other and listed as `(empty)`, so a
1157
1212
  file `naro env pull` wrote for a project holding one imports back. Past
1158
1213
  100 variables, and after you say yes, it reads the project's binding
1159
- names once (its storage bindings, `ASSETS`, and `DB` on a project with
1160
- the managed database) and fails `VALIDATION_FAILED`
1214
+ names once (`ASSETS`, and `DB` on a project with the managed database) and fails `VALIDATION_FAILED`
1161
1215
  `<KEY> is already used by a storage binding.` for the first key of the
1162
1216
  file that is one, before the first request; the route refuses such a
1163
1217
  key per request, which left the batches before it saved. Up to 100
@@ -1591,7 +1645,7 @@ RENAME` the way the control plane now reads it: a column rename whose
1591
1645
  and `Next.js <version> is too old to deploy. Naro deploys Next.js 15 or newer. Upgrade to Next.js 16.`
1592
1646
  - A Next.js app built with vinext reads its bindings with
1593
1647
  `getCloudflareContext().env`, as under OpenNext. Before, `env` was missing
1594
- there, so `env.MY_BUCKET` was `undefined` and nothing was thrown. naro
1648
+ there, so `env.MY_BUCKET` was `undefined` and nothing was thrown. Naro
1595
1649
  writes this Worker entry as `naro-worker.js`, so a project with its own
1596
1650
  file of that name is not built with vinext.
1597
1651
  - Build logs hide more secrets: upper-case names that end in `TOKEN`,
@@ -1617,7 +1671,7 @@ RENAME` the way the control plane now reads it: a column rename whose
1617
1671
 
1618
1672
  ### 0.17.0
1619
1673
 
1620
- - `naro domains add` prints one CNAME record and no TXT records. naro
1674
+ - `naro domains add` prints one CNAME record and no TXT records. Naro
1621
1675
  registers the domain once the CNAME points at it, usually within about five
1622
1676
  minutes. The status line reads `Waiting for DNS — add the CNAME above; naro
1623
1677
  connects it within about five minutes.` `naro domains verify` registers it at
@@ -1725,10 +1779,10 @@ server.`), and the CLI prints that message. Before, the CLI got a 500.
1725
1779
  and preview together (one switch, so `--env` is refused there).
1726
1780
  - `naro protection` shows whether the project's preview URL is protected and
1727
1781
  whether a bypass secret is set. Protection is on by default: only members
1728
- of the project can open `<name>-preview.naro.sh`, after signing in to naro.
1782
+ of the project can open `<name>-preview.naro.sh`, after signing in to Naro.
1729
1783
  A GET or HEAD that is a page navigation (`Sec-Fetch-Mode: navigate`), or that
1730
1784
  sends no `Sec-Fetch-Mode` and an `Accept` including `text/html`, is
1731
- redirected to the naro sign-in; every other request gets
1785
+ redirected to the Naro sign-in; every other request gets
1732
1786
  `401 PREVIEW_PROTECTED`. A request the browser sends without cookies (a
1733
1787
  `<link rel="manifest">` without `crossorigin="use-credentials"`) gets 401
1734
1788
  too.
@@ -1745,7 +1799,7 @@ server.`), and the CLI prints that message. Before, the CLI got a 500.
1745
1799
  (public or private, the largest file, the types taken), and `ls`, `cp`
1746
1800
  and `rm` work on `naro://<bucket>/<path>` with the project's service key
1747
1801
  (`NARO_SERVICE_KEY`, or fetched with a warning) — the bytes go to the
1748
- project's backend, not through naro. One request carries 50 MiB at most; a
1802
+ project's backend, not through Naro. One request carries 50 MiB at most; a
1749
1803
  larger file goes in parts since 0.16.0 (under 4 GiB).
1750
1804
  `bucket update --public`, `empty`, `remove` and `rm` ask first; without a
1751
1805
  terminal they need `--yes` (`CONFIRMATION_REQUIRED` otherwise, nothing
@@ -1784,7 +1838,7 @@ server.`), and the CLI prints that message. Before, the CLI got a 500.
1784
1838
  INT, REAL, FLOA, DOUB, NUM, DEC, BOOL or BIT (a form's `"true"` for a
1785
1839
  BOOLEAN, `"high"` for an INTEGER), even when no policy reads the column.
1786
1840
  The backend worker takes this on at the project's next deploy or
1787
- `naro backend enable`, not when naro itself updates. Before that, look for
1841
+ `naro backend enable`, not when Naro itself updates. Before that, look for
1788
1842
  such rows: `naro db query "select count(*) from t where typeof(c) = 'text'"`
1789
1843
  for each number or boolean column — a count above 0 means a client writes
1790
1844
  strings there and needs fixing first.
package/dist/args.d.ts CHANGED
@@ -1,4 +1,53 @@
1
1
  export interface GlobalFlags {
2
+ /**
3
+ * `naro dns records add|update`: the record's fields, passed as typed — the
4
+ * control plane checks them (apps/web/src/lib/dns-records.ts). CAA takes
5
+ * `--caa-flags --tag --value`, SRV `--priority --weight --port --target`.
6
+ */
7
+ content?: string | undefined;
8
+ ttl?: string | undefined;
9
+ priority?: string | undefined;
10
+ caaFlags?: string | undefined;
11
+ tag?: string | undefined;
12
+ value?: string | undefined;
13
+ weight?: string | undefined;
14
+ port?: string | undefined;
15
+ target?: string | undefined;
16
+ /** `naro team set --slug <new-slug>`: the team's new slug. */
17
+ slug?: string | undefined;
18
+ /** `naro team members set <user-id> --role <role>`; the server checks it. */
19
+ role?: string | undefined;
20
+ /**
21
+ * `naro firewall add --kind <ip|country|path|rate_limit> --value <value>`;
22
+ * a rate limit also takes `--rate-limit <n> --period <seconds>`. Strings, as
23
+ * typed: the control plane checks them (apps/web/src/lib/firewall-input.ts).
24
+ */
25
+ kind?: string | undefined;
26
+ rateLimit?: string | undefined;
27
+ period?: string | undefined;
28
+ /** `naro firewall add --disabled`: save the rule switched off. */
29
+ disabled?: boolean | undefined;
30
+ /** `naro flags add <name> --on`: the new flag starts on. */
31
+ on?: boolean | undefined;
32
+ /**
33
+ * `naro project set`: the General settings, as typed — the control plane
34
+ * checks them. An empty value clears the setting back to the preset.
35
+ */
36
+ subdomain?: string | undefined;
37
+ framework?: string | undefined;
38
+ buildCommand?: string | undefined;
39
+ outputDir?: string | undefined;
40
+ /** `naro project set --vinext on|off`. */
41
+ vinext?: string | undefined;
42
+ /** `naro storage sign --expires <seconds>`: 1-3600, an hour by default. */
43
+ expires?: string | undefined;
44
+ /** `naro storage sign --download`: the browser saves the file. */
45
+ download?: boolean | undefined;
46
+ /** `naro functions update <name> --verify-jwt on|off`. */
47
+ verifyJwt?: string | undefined;
48
+ /** `naro functions invoke <name> --method <M> --data <body>`. */
49
+ method?: string | undefined;
50
+ data?: string | undefined;
2
51
  json: boolean;
3
52
  yes: boolean;
4
53
  debug: boolean;