naro-cli 0.19.0 → 0.20.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 +313 -13
- package/dist/{chunk-DEEFHVDZ.js → chunk-SAA66XLD.js} +2082 -410
- package/dist/deploy.d.ts +3 -3
- package/dist/deploy.js +2 -2
- package/dist/index.js +415 -42
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -93,9 +93,12 @@ naro env add DATABASE_URL production
|
|
|
93
93
|
naro env remove DATABASE_URL The production, preview and all values; an environment's only with its name
|
|
94
94
|
(naro env remove DATABASE_URL qa)
|
|
95
95
|
naro env pull [.env.local] Preview's values by default; --env production, or --env qa for an environment
|
|
96
|
-
(its own value wins over all; an unknown name fails before anything is written
|
|
96
|
+
(its own value wins over all; an unknown name fails before anything is written,
|
|
97
|
+
and so does a value no dotenv line reads back)
|
|
97
98
|
naro env import .env.qa qa Upload every variable in a dotenv file to one target (all by default; asks first,
|
|
98
|
-
--yes in CI; invalid
|
|
99
|
+
--yes in CI; an unclosed quote, an invalid key, ASSETS or a value over 5 KB
|
|
100
|
+
stops it before any request, and so does a key a storage binding already uses
|
|
101
|
+
when there are over 100 variables; an empty value is uploaded and shown (empty))
|
|
99
102
|
|
|
100
103
|
naro environments List the project's environments: address, branch, protection, and how many the plan allows
|
|
101
104
|
naro environments create qa --branch qa
|
|
@@ -195,6 +198,7 @@ naro policy remove todos Drop every policy on the table: back to deny
|
|
|
195
198
|
|
|
196
199
|
naro storage Naro Storage: on or off, limits, usage, today's operations, buckets
|
|
197
200
|
naro storage enable Turn it on: the project's R2 bucket, bound to the backend
|
|
201
|
+
naro storage disable [--yes] Turn it off and keep the files: Storage calls and file URLs answer 404 until enable (asks first)
|
|
198
202
|
naro storage bucket create avatars --public --file-size-limit 5MiB --allowed-mime-types image/png,image/jpeg
|
|
199
203
|
naro storage bucket update avatars --private | --file-size-limit none | --allowed-mime-types any
|
|
200
204
|
naro storage bucket update docs --public (asks first: anyone with an object's URL can download it)
|
|
@@ -202,10 +206,12 @@ naro storage bucket list | empty <name> | remove <name> [--empty] (empty and r
|
|
|
202
206
|
naro storage ls naro://avatars/u1 [--recursive] [--search <text>] Names that start with <text>, ASCII case ignored
|
|
203
207
|
naro storage cp ./me.png naro://avatars/u1/me.png [--upsert] Up to the object limit, under 4 GiB (over 50 MiB in parts), with the service key
|
|
204
208
|
naro storage cp naro://docs/team-1/plan.pdf ./ Replaces a local file of the same name
|
|
209
|
+
naro storage cp naro://docs/a.pdf naro://docs/b.pdf [--upsert] Inside one bucket, up to 5 GiB − 5 MiB
|
|
210
|
+
naro storage mv naro://docs/a.pdf naro://docs/old/a.pdf Inside one bucket, up to 5 GiB − 5 MiB; never replaces
|
|
205
211
|
naro storage rm naro://avatars/u1/old.png [--recursive] (asks first)
|
|
206
212
|
naro storage rm naro://avatars/u1/ --recursive Everything under u1/; written u1, an object u1 too
|
|
207
213
|
|
|
208
|
-
naro promote <deployment-id>
|
|
214
|
+
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
|
|
209
215
|
naro rollback [deployment-id] Back to the previous production build
|
|
210
216
|
```
|
|
211
217
|
|
|
@@ -326,10 +332,11 @@ four actions; any other new table is closed to the Data API until you give it
|
|
|
326
332
|
a policy (`CREATE POLICY` in a migration, or `naro policy create` or
|
|
327
333
|
`naro policy set`; the command says so).
|
|
328
334
|
Policies go with their table, as in Postgres and as `naro db push` does it,
|
|
329
|
-
in the same migration: a drop removes the table's policies,
|
|
335
|
+
in the same migration: a drop removes the table's policies, a rename
|
|
330
336
|
moves them to the new name and rewrites the policies of other tables that
|
|
331
|
-
read it
|
|
332
|
-
|
|
337
|
+
read it, and `rename-column` rewrites every policy that reads the column,
|
|
338
|
+
an owner rule's column included (the command says which). A rename such a
|
|
339
|
+
policy cannot follow is refused before anything runs. A table the command creates, or renames onto a
|
|
333
340
|
name, never inherits what an earlier table of that name left there: that is
|
|
334
341
|
removed first. A change that fails changes no policy. Whatever a command
|
|
335
342
|
removes it prints so it can be made again: as `CREATE POLICY` statements, which
|
|
@@ -588,8 +595,16 @@ tables: a policy on a table that does not exist
|
|
|
588
595
|
(`relation "nope" does not exist`), a name already taken, or a 33rd policy on
|
|
589
596
|
one table fails the whole request with `400 DATABASE_QUERY_FAILED`, names the
|
|
590
597
|
statement, and applies nothing — not even the `CREATE TABLE` before it. Policy
|
|
591
|
-
statements,
|
|
592
|
-
`params` (`400 VALIDATION_FAILED`): write
|
|
598
|
+
statements, statements that create, drop or rename a table, and statements
|
|
599
|
+
that add a generated column take no `params` (`400 VALIDATION_FAILED`): write
|
|
600
|
+
the values into the SQL.
|
|
601
|
+
|
|
602
|
+
`ALTER TABLE t ADD COLUMN c … AS (…)` computes the generated column for the
|
|
603
|
+
rows already in `t` right after it, as Postgres does: a row it cannot be
|
|
604
|
+
computed for (`json_extract` over text that is not JSON) fails the request
|
|
605
|
+
with SQLite's error (`400 DATABASE_QUERY_FAILED` `malformed JSON:
|
|
606
|
+
SQLITE_ERROR`) and nothing changes. Fix those rows first, in an earlier
|
|
607
|
+
statement.
|
|
593
608
|
|
|
594
609
|
Policies go with their table, as in Postgres: `DROP TABLE` drops them, and a
|
|
595
610
|
new table never inherits the leftovers of an earlier one with the same name
|
|
@@ -601,6 +616,11 @@ the `CREATE POLICY` statements again after the rename, in the same migration.
|
|
|
601
616
|
A plain `ALTER TABLE a RENAME TO b` in a migration moves `a`'s policies to `b`,
|
|
602
617
|
and a policy of another table that reads `a` is written to read `b` — do not
|
|
603
618
|
create them again on `b`: a policy of the same name already there is refused.
|
|
619
|
+
`ALTER TABLE t RENAME COLUMN c TO d` writes every policy that reads `t.c` —
|
|
620
|
+
`t`'s own, another table's through a subquery, an owner rule's column — to
|
|
621
|
+
read `t.d`, so each keeps reading the column it read, as in Postgres. A rename
|
|
622
|
+
a policy cannot follow, such as giving a column the name of a dropped one that
|
|
623
|
+
a policy still reads, is refused before anything runs.
|
|
604
624
|
`naro db table`, the table editor and MCP do the same.
|
|
605
625
|
The answer's `warnings` lists the policies a migration removed, with SQL you
|
|
606
626
|
can paste; it also says when the project has no backend yet (the policies are
|
|
@@ -826,6 +846,277 @@ An `--update-check` you give replaces the default: without
|
|
|
826
846
|
|
|
827
847
|
## Release notes
|
|
828
848
|
|
|
849
|
+
### 0.20.0
|
|
850
|
+
|
|
851
|
+
0.19.1 went out on 2026-10-24 without these.
|
|
852
|
+
|
|
853
|
+
- `naro promote <deployment-id> --to <environment>` publishes a build to a
|
|
854
|
+
named environment. `--to` takes `production` (what no `--to` does) or an
|
|
855
|
+
environment's slug; an empty value, only blanks or `preview` fails before
|
|
856
|
+
any request with `VALIDATION_FAILED`
|
|
857
|
+
`--to must be production or an environment name.` The usage line is
|
|
858
|
+
`Usage: naro promote <deployment-id> [--to <environment>]`.
|
|
859
|
+
- Before it asks, it says what the promotion will do, from the control
|
|
860
|
+
plane's preview (`GET …/promote?target=`, which changes nothing):
|
|
861
|
+
`▸ rebuild: builds the same commit again with qa's variables` or
|
|
862
|
+
`▸ reupload: publishes the stored build`, then each warning as
|
|
863
|
+
`⚠ <warning>`. Without `--to` the same line is printed for production
|
|
864
|
+
(`… with production's variables`); that is one request more than 0.19.1
|
|
865
|
+
sent.
|
|
866
|
+
- A build moving between an environment and another surface (a preview or
|
|
867
|
+
production build to `qa`, a `qa` build to `staging` or to production) is
|
|
868
|
+
built again from its commit with the target's variables, and counts
|
|
869
|
+
against the plan's builds. Any other build is published as stored: one
|
|
870
|
+
promoted within its own surface, and a preview to production.
|
|
871
|
+
- The question is `Promote <id> to qa (<subdomain>--qa)?`; for production it
|
|
872
|
+
is the one it always was, `Promote <id> to production (<subdomain>)?`.
|
|
873
|
+
`--json` or no terminal without `--yes` still fails
|
|
874
|
+
`CONFIRMATION_REQUIRED`.
|
|
875
|
+
- Progress is `▸ promoting <id> to qa (rebuild)` (`(reupload)`), and the
|
|
876
|
+
result `✅ qa now serves a rebuild of <id>` or `✅ qa now serves <id>`; for
|
|
877
|
+
production `✅ Production now serves a rebuild of <id>` or, as before,
|
|
878
|
+
`✅ Production now serves <id>`. A rebuild is waited for up to 15 minutes
|
|
879
|
+
(a published build, 5 as before), and a failed one fails with its own
|
|
880
|
+
code and message. While a rebuild runs its build log lines print the way
|
|
881
|
+
`naro logs --type build --follow` prints them (`[BUILDING] next build`,
|
|
882
|
+
`[BUILDING] ✗ <error>`), on stderr with `--json` so stdout stays one
|
|
883
|
+
object; a published build prints none.
|
|
884
|
+
- `--json` adds `target` (`null` without `--to`) and `mode` (`rebuild` or
|
|
885
|
+
`reupload`): `{ deploymentId, sourceDeploymentId, projectId, target, mode, status, url }`.
|
|
886
|
+
`naro rollback`'s result gains `mode` too (as MCP's `rollback_deployment`
|
|
887
|
+
says it) and has no `target`: a rollback is always production's.
|
|
888
|
+
- `409 PROMOTE_NEEDS_GIT_SOURCE`
|
|
889
|
+
`Only deployments built from Git can be promoted to another environment. Deploy the code again with naro deploy instead.`
|
|
890
|
+
for a deployment `naro deploy` uploaded. This and every other refusal of
|
|
891
|
+
the preview (`404 ENVIRONMENT_NOT_FOUND` `Environment not found.`) stop
|
|
892
|
+
it in the control plane's words before it asks, and nothing is promoted.
|
|
893
|
+
- A rebuild checks out the pinned commit as a detached HEAD, not the
|
|
894
|
+
branch, so a build script that reads the branch name from git
|
|
895
|
+
(`git branch --show-current`, `git rev-parse --abbrev-ref HEAD`) sees
|
|
896
|
+
none.
|
|
897
|
+
- Against a control plane from before named environments 2a, which has no
|
|
898
|
+
preview (it answers 405) and whose promote ignores the target and
|
|
899
|
+
republishes to production, `--to <environment>` stops before it promotes
|
|
900
|
+
anything: `PROMOTE_TARGET_UNSUPPORTED`
|
|
901
|
+
`This control plane cannot promote to an environment yet. Deploy the latest web first, then try again.`
|
|
902
|
+
With no `--to` or `--to production` the 405 is ignored: no preview line,
|
|
903
|
+
and the promotion goes as it always did.
|
|
904
|
+
- `--to` belongs to `naro promote`; `naro rollback` refuses it before any
|
|
905
|
+
request with `VALIDATION_FAILED`
|
|
906
|
+
`--to is for naro promote: naro rollback always rolls production back.`
|
|
907
|
+
(it always targets production, and ignoring `--to` would roll production
|
|
908
|
+
back for someone who named an environment).
|
|
909
|
+
- Any other command given `--to` fails before any request with
|
|
910
|
+
`VALIDATION_FAILED` `--to is only for naro promote.`, so a flag a command
|
|
911
|
+
does not read is never dropped silently.
|
|
912
|
+
- `naro promote` and `naro rollback` refuse `--env` and any word after the
|
|
913
|
+
deployment id before any request, with `VALIDATION_FAILED`
|
|
914
|
+
`--env is not an option of naro promote: use --to <environment>.`,
|
|
915
|
+
`--env is not an option of naro rollback: naro rollback always rolls production back.`
|
|
916
|
+
or the usage line (`Usage: naro promote <deployment-id> [--to <environment>]`,
|
|
917
|
+
`Usage: naro rollback [deployment-id]`), instead of acting on production for
|
|
918
|
+
someone who named an environment (`naro promote d1 --env qa --yes` and
|
|
919
|
+
`naro promote d1 qa --yes` promoted to production in 0.19.1).
|
|
920
|
+
- A control plane with named environments 2a rebuilds a deployment of an
|
|
921
|
+
environment that is promoted to production, which it used to refuse with
|
|
922
|
+
`400 DEPLOYMENT_NOT_PROMOTABLE`. `naro promote <id>` says so before it
|
|
923
|
+
asks (`▸ rebuild: … with production's variables`) and waits up to 15
|
|
924
|
+
minutes; `naro rollback <id>` waits 15 minutes for such a rebuild too and
|
|
925
|
+
prints `✅ Production now serves a rebuild of <id>`. The build that
|
|
926
|
+
`naro rollback` picks on its own is never one.
|
|
927
|
+
- `naro storage disable [--yes]` turns the project's Storage off and keeps
|
|
928
|
+
its files (Storage 3-1k). It asks first —
|
|
929
|
+
`Turn Storage off for this project? Its Storage calls and file URLs answer 404 until naro storage enable; buckets and files are kept.`
|
|
930
|
+
— and without a terminal or with `--json` only `--yes` answers it. The
|
|
931
|
+
backend is uploaded again without the bucket: the app's Storage calls and
|
|
932
|
+
file URLs answer `404 STORAGE_NOT_ENABLED` until `naro storage enable`
|
|
933
|
+
binds the same bucket again, and the buckets, the files and their storage
|
|
934
|
+
cost stay. To delete the files instead, remove the buckets with
|
|
935
|
+
`naro storage bucket remove <name> --empty` while Storage is on. Storage
|
|
936
|
+
that was never turned on prints `Storage is already off.` and changes
|
|
937
|
+
nothing; Storage that is already off is finished without asking again (a
|
|
938
|
+
turn-off whose upload stopped answers `BACKEND_PROVISION_FAILED` and says
|
|
939
|
+
to run it again).
|
|
940
|
+
- `naro storage` says
|
|
941
|
+
`Storage: off since <YYYY-MM-DD HH:MM> UTC — buckets and files are kept`
|
|
942
|
+
while it is off, with the buckets.
|
|
943
|
+
- `naro storage ls`, `cp`, `mv` and `rm` read the Storage state before the
|
|
944
|
+
service key and stop with `STORAGE_OFF`
|
|
945
|
+
``Storage is turned off for this project. Turn it on with `naro storage enable` first.``
|
|
946
|
+
while it is off. `naro storage bucket create` on Storage that is off gets
|
|
947
|
+
the control plane's `409 STORAGE_OFF`: it turns Storage on by itself only
|
|
948
|
+
when Storage was never on.
|
|
949
|
+
- Published naro-cli 0.19.1 and earlier show Storage that is off as `off`
|
|
950
|
+
and pass the backend's `404 STORAGE_NOT_ENABLED` on from `ls`, `cp`,
|
|
951
|
+
`mv` and `rm`; their `bucket create` stops at `409 STORAGE_OFF` too.
|
|
952
|
+
|
|
953
|
+
### 0.19.1
|
|
954
|
+
|
|
955
|
+
0.19.0 went out on 2026-10-19 without these.
|
|
956
|
+
|
|
957
|
+
- `naro git connect` says what to do when the link alone is not enough. The
|
|
958
|
+
control plane now records, for each team, only the repositories the people
|
|
959
|
+
who connected GitHub could read themselves (known-issues #232), and for an
|
|
960
|
+
account the team already holds it hands out an import link
|
|
961
|
+
(`/api/github/authorize`) rather than an install one. Without a terminal
|
|
962
|
+
or with `--json` the error reads
|
|
963
|
+
`Naro cannot reach <owner/repo> yet. Open <url> to give Naro access (if the repository is not among the ones the Naro GitHub App was granted on GitHub, add it there first), then run: naro git connect`
|
|
964
|
+
(0.19.0: `… Install the Naro GitHub App at <url>, then run: naro git connect`);
|
|
965
|
+
in a terminal, after `Opening <url>`, it adds
|
|
966
|
+
`If the repository is not among the ones the Naro GitHub App was granted on GitHub, add it there first.`
|
|
967
|
+
- `deployDirectory`, the library export the MCP server uses, now refuses
|
|
968
|
+
`production: true` with any `environment` (`""` too):
|
|
969
|
+
`VALIDATION_FAILED` `environment and production cannot be used together.`,
|
|
970
|
+
the control plane's own words, before any value is read, asked for or
|
|
971
|
+
sent and before the deployment is created (the MCP `deploy` tool still
|
|
972
|
+
signs in and looks the team up first). 0.19.0 sent both and left the
|
|
973
|
+
refusal to the control plane (a caller passing `onMissingEnv` was asked
|
|
974
|
+
for missing values first); a control plane from before named
|
|
975
|
+
environments 1b-2 ignores `environment` and would deploy to production.
|
|
976
|
+
- `naro env remove KEY` with no target, for a key only environments hold,
|
|
977
|
+
fails `ENV_NOT_FOUND`
|
|
978
|
+
`No KEY variable found outside named environments. Pass the environment to remove it: qa, staging.`
|
|
979
|
+
(`--json` details: `key`, `environments`) and still removes nothing. It
|
|
980
|
+
said `No KEY variable found.`, which a key no row has still gets.
|
|
981
|
+
- `naro env import` refuses more before any request, in this order:
|
|
982
|
+
`Cannot read <file>.`, `Unclosed quote in <file> at line <n>.`,
|
|
983
|
+
`No variables found in <file>.`, `Invalid keys in <file>: A-B, 1X.`,
|
|
984
|
+
`ASSETS is reserved for the project's static files; pick another name.`
|
|
985
|
+
(the env route's words) or `Values over 5 KB in <file>: BIG.` An empty
|
|
986
|
+
value (`KEY=`) is uploaded like any other and listed as `(empty)`, so a
|
|
987
|
+
file `naro env pull` wrote for a project holding one imports back. Past
|
|
988
|
+
100 variables, and after you say yes, it reads the project's binding
|
|
989
|
+
names once (its storage bindings, `ASSETS`, and `DB` on a project with
|
|
990
|
+
the managed database) and fails `VALIDATION_FAILED`
|
|
991
|
+
`<KEY> is already used by a storage binding.` for the first key of the
|
|
992
|
+
file that is one, before the first request; the route refuses such a
|
|
993
|
+
key per request, which left the batches before it saved. Up to 100
|
|
994
|
+
variables ask nothing: one request is atomic on the server. Any other
|
|
995
|
+
refusal of a later request (a role, a race) still leaves the earlier
|
|
996
|
+
ones saved.
|
|
997
|
+
- Dotenv files are read the way Next.js reads them (dotenv 16, what
|
|
998
|
+
`next dev` runs), for `naro env import` and for the values `naro deploy`
|
|
999
|
+
reads from `.env.local` once you agree, so the value saved is the one
|
|
1000
|
+
your app saw locally. A value in `'`, `"` or `` ` `` runs to its closing
|
|
1001
|
+
quote over several lines (a PEM key, as `.env.local` for Next.js often
|
|
1002
|
+
holds one). Inside double quotes `\n` and `\r` are a line break and a
|
|
1003
|
+
carriage return and every other backslash stays as written (`\\` is two,
|
|
1004
|
+
`\"` a backslash and a quote); single quotes and backticks are read as
|
|
1005
|
+
written. An unquoted value ends at its first `#` (`abc#def` is `abc`).
|
|
1006
|
+
CRLF ends a line, inside quotes too. A quote that never closes stays in
|
|
1007
|
+
the value, as Next.js reads it (`naro env import` refuses the file). Unlike
|
|
1008
|
+
Next.js, `$VAR` and `${VAR}` are not expanded: a value built from another
|
|
1009
|
+
variable is saved as written. Before, a multi-line value was cut to its
|
|
1010
|
+
first line, opening quote included, and a base64 line ending in `=`
|
|
1011
|
+
became a key of its own.
|
|
1012
|
+
- `naro env pull` writes each value so that dotenv and `naro env import`
|
|
1013
|
+
read it back as it was (known-issues #224): bare when nothing in it needs
|
|
1014
|
+
quoting, else in single quotes, in backticks when it holds `'`, or in
|
|
1015
|
+
double quotes when it holds `'` and `` ` ``. A value with a carriage
|
|
1016
|
+
return is written in double quotes with the carriage return as `\r`
|
|
1017
|
+
(dotenv reads a carriage return written as is for a line break). A value
|
|
1018
|
+
ending in a backslash is written bare. Next.js reads every value back as
|
|
1019
|
+
it was except those with a `$`: it expands `$NAME` and `${NAME}`
|
|
1020
|
+
(dotenv-expand) whatever the quotes, so a bcrypt hash `$2b$10$…` is cut
|
|
1021
|
+
down (to `""`, or to what follows its first `.` or `/`) and `pa$$word` is
|
|
1022
|
+
`pa$` for `next dev`, while `naro env import` reads them
|
|
1023
|
+
unchanged. A value no dotenv line reads back fails before the overwrite
|
|
1024
|
+
question and before anything is written, with `VALIDATION_FAILED`
|
|
1025
|
+
``Cannot write KEY1, KEY2 to a dotenv file: their values hold ', " and ` together.``
|
|
1026
|
+
or, for the rarer carriage return beside `"`, backslash at the end, or
|
|
1027
|
+
written-out `\n` beside `'` and `` ` ``,
|
|
1028
|
+
`Cannot write KEY to a dotenv file: dotenv would not read their values back unchanged.`
|
|
1029
|
+
followed by how to store such a value: without carriage returns or one of
|
|
1030
|
+
the quote characters (a service-account JSON from a CRLF file:
|
|
1031
|
+
`tr -d '\r' < sa.json | naro env add KEY`), or read it with
|
|
1032
|
+
`naro env list --reveal` (`--json` details: `keys`). Before, it wrote such
|
|
1033
|
+
values in double quotes with `\` and `"` escaped, which Next.js reads with
|
|
1034
|
+
the backslashes: pull a file an earlier version wrote
|
|
1035
|
+
again.
|
|
1036
|
+
- On a backend from before named policies, renaming a column answers
|
|
1037
|
+
`409 BACKEND_OUTDATED` until `naro backend enable` runs, as creating,
|
|
1038
|
+
dropping or renaming a table does — through `naro db table`,
|
|
1039
|
+
`naro db push` and `naro db query` alike.
|
|
1040
|
+
- `naro db table rename-column`, and `ALTER TABLE … RENAME COLUMN` in
|
|
1041
|
+
`naro db push` and `naro db query`, rewrite the Data API policies that read
|
|
1042
|
+
the column, an owner rule's column included (known-issues #90): the
|
|
1043
|
+
command prints
|
|
1044
|
+
`⚠ Rewrote 1 policy that read members.user_id to read members.uid: docs.team.`.
|
|
1045
|
+
Before, a policy reading the old name answered `500 POLICY_INVALID`, and
|
|
1046
|
+
two columns swapped in one change left it reading the other column. The
|
|
1047
|
+
warning that told you to run `naro policy set <table> --owner <new>` is
|
|
1048
|
+
gone. A rename a policy cannot follow is refused before anything runs.
|
|
1049
|
+
- `naro db push` and `naro db reset` check a migration's `ALTER TABLE …
|
|
1050
|
+
RENAME` the way the control plane now reads it: a column rename whose
|
|
1051
|
+
names cannot be read (`ALTER TABLE t RENAME COLUMN c TO` with nothing
|
|
1052
|
+
after it, `t.c` for the column) is
|
|
1053
|
+
`Statement <i> of <n>: the column name could not be read.` before anything
|
|
1054
|
+
runs. Before, it reached D1 and failed as SQLite's syntax error.
|
|
1055
|
+
- `naro storage mv naro://<bucket>/<from> naro://<bucket>/<to>` moves an
|
|
1056
|
+
object inside its bucket, and `naro storage cp` between two `naro://`
|
|
1057
|
+
paths of one bucket copies one there (Storage 3-1i), each up to
|
|
1058
|
+
5 GiB − 5 MiB. Over that the backend answers `413 OBJECT_TOO_LARGE`:
|
|
1059
|
+
`Objects over 5,363,466,240 bytes (5 GiB − 5 MiB) cannot be copied or moved.`
|
|
1060
|
+
A destination ending in `/`, or the bucket alone (`naro://docs`), takes the
|
|
1061
|
+
object's name. `mv` never replaces an
|
|
1062
|
+
object — a name that is taken answers `409 OBJECT_EXISTS`
|
|
1063
|
+
`Object <path> already exists in bucket <bucket>. A move never replaces an object: remove it or choose another name.`
|
|
1064
|
+
— and takes no `--upsert`, `--content-type` or `--cache-control`; `cp`
|
|
1065
|
+
replaces one with `--upsert` and keeps the type and cache-control
|
|
1066
|
+
(`--content-type` and `--cache-control` are refused).
|
|
1067
|
+
Both refuse two buckets before any request:
|
|
1068
|
+
`naro storage cp and mv work inside one bucket: both sides must be in naro://<bucket>.`
|
|
1069
|
+
A name an upload or a download would refuse is refused before any request,
|
|
1070
|
+
in the same words (`INVALID_PATH`
|
|
1071
|
+
`The object path is not valid: it has an empty segment (//).`), and
|
|
1072
|
+
`--recursive` is refused rather than dropped:
|
|
1073
|
+
`naro storage mv takes no --recursive: it moves one object, naro://<bucket>/<path>. --recursive is for naro storage ls and rm.`
|
|
1074
|
+
(`cp` between two `naro://` paths:
|
|
1075
|
+
`A copy inside Storage takes no --recursive: it copies one object, naro://<bucket>/<path>. --recursive is for naro storage ls and rm.`).
|
|
1076
|
+
A project backend from before this release answers them with
|
|
1077
|
+
`BACKEND_OUTDATED`:
|
|
1078
|
+
``The project backend is older than this Storage command. Run `naro backend enable` to update it, then try again.``
|
|
1079
|
+
`cp` between two `naro://` paths used to answer
|
|
1080
|
+
`Copying inside Storage is not supported yet.` `--json` of a copy carries
|
|
1081
|
+
`object` (`{ id, path, fullPath }`).
|
|
1082
|
+
- `naro db lint` measures a `storage.objects` move too (Storage 3-1i): a
|
|
1083
|
+
move binds its new name at every read of the UPDATE policy's check, so a
|
|
1084
|
+
set whose UPDATE check reads `name` many times can now be refused before
|
|
1085
|
+
it is pushed, though an overwrite under it fits; the backend would answer
|
|
1086
|
+
every move `500 POLICY_INVALID`. A copy's claim is an upload's and changes
|
|
1087
|
+
nothing.
|
|
1088
|
+
- A table's policy can read `storage.objects` in a subquery (Storage 3-1j),
|
|
1089
|
+
and so can a `realtime.messages` policy. `naro db push --dry-run`,
|
|
1090
|
+
`naro db reset` and `naro policy create` take such a policy here, where
|
|
1091
|
+
0.18.0 and 0.19.0 refused it locally, before changing anything, with
|
|
1092
|
+
`A policy cannot read storage.objects in a subquery yet at character <n>.`,
|
|
1093
|
+
and `naro db lint` no longer reports a stored one as `rls_policy_invalid`
|
|
1094
|
+
(known-issues #227). `naro db reset` lists a stored one your files do not
|
|
1095
|
+
make with the SQL that keeps it, where 0.18.0 and 0.19.0 showed
|
|
1096
|
+
`-- Policy <p> on <t> cannot be read (…)` in its place (in `--json` too)
|
|
1097
|
+
and, once confirmed, dropped it with no SQL to make it again. The backend reads it through the caller's
|
|
1098
|
+
`storage.objects` policies and only files that are fully there (not still
|
|
1099
|
+
uploading or being removed); write `bucket_id = '<bucket>'` in the
|
|
1100
|
+
subquery (`bucket_id in ('a', 'b')` for several buckets). A check never
|
|
1101
|
+
finds a new file being uploaded or copied, or a move's new name, as in
|
|
1102
|
+
Postgres. A backend
|
|
1103
|
+
from before Storage 3-1j answers such a policy with
|
|
1104
|
+
`409 BACKEND_OUTDATED`:
|
|
1105
|
+
``storage.objects is not available on this backend yet. Run `naro backend enable` to update it.``
|
|
1106
|
+
`naro db lint` measures those policies inside the table's statement, and
|
|
1107
|
+
for a signed-in caller whose email is not verified too.
|
|
1108
|
+
- `naro db reset` refuses, before it drops anything (and on `--dry-run`
|
|
1109
|
+
too), migration files the backend would stop at for Storage: a policy that
|
|
1110
|
+
reads `storage.objects` in a subquery while the backend's ledger lacks
|
|
1111
|
+
system migration 7 (it reads the ledger only when a file has one), and
|
|
1112
|
+
a statement that needs `storage.objects` (CREATE POLICY, DROP POLICY without
|
|
1113
|
+
IF EXISTS, the `naro:owner` COMMENT) on a backend from before Storage or a
|
|
1114
|
+
project with none. It fails `BACKEND_OUTDATED`
|
|
1115
|
+
``0002_b.sql needs storage.objects (statement 2 of 2), which is not available on this backend yet, so the reset would stop there with the schema already dropped. Nothing was changed. Run `naro backend enable` to update it, then try again.``
|
|
1116
|
+
(`--json` details: `migration`, `statement`). Before, the checks passed,
|
|
1117
|
+
the schema was dropped and the re-apply stopped at the control plane's
|
|
1118
|
+
`409 BACKEND_OUTDATED`, with `The schema is dropped and the re-apply stopped.`
|
|
1119
|
+
|
|
829
1120
|
### 0.19.0
|
|
830
1121
|
|
|
831
1122
|
- `naro environments` manages a project's named environments, QA or staging
|
|
@@ -905,9 +1196,10 @@ An `--update-check` you give replaces the default: without
|
|
|
905
1196
|
deploy gets. A production deploy now lists a key set only for preview as
|
|
906
1197
|
missing, and a preview deploy one set only for production; an environment
|
|
907
1198
|
deploy counts the `all` values and that environment's own. On an
|
|
908
|
-
environment deploy, the values
|
|
909
|
-
|
|
910
|
-
|
|
1199
|
+
environment deploy, the values the deploy reads from your dotenv file
|
|
1200
|
+
(once you agree to it) are saved for that environment alone, so a
|
|
1201
|
+
developer, who cannot change `all`, has them saved instead of listed under
|
|
1202
|
+
`⚠ skipped env:`. Production and preview deploys
|
|
911
1203
|
still save them for `all`. The hint names the environment too:
|
|
912
1204
|
`npx naro-cli env add DATABASE_URL qa`.
|
|
913
1205
|
- `naro env add` and `naro env remove` take an environment's slug as the
|
|
@@ -948,6 +1240,11 @@ An `--update-check` you give replaces the default: without
|
|
|
948
1240
|
reads as `KEY`. Values with `\"` or `\\` inside double quotes are read as
|
|
949
1241
|
written, not unescaped, so a file `naro env pull` wrote with such a value
|
|
950
1242
|
does not import back as it was (known-issues #224).
|
|
1243
|
+
A value in quotes that runs over several lines (a PEM key) is cut to
|
|
1244
|
+
its first line, opening quote included, and a base64 line ending in
|
|
1245
|
+
`=` becomes a key of its own, though the result says `✅ Imported`.
|
|
1246
|
+
The values `naro deploy` reads from `.env.local` once you agree are cut
|
|
1247
|
+
the same way, with no warning. Use 0.19.1 for such a file.
|
|
951
1248
|
- `naro env add` with a value typed at the prompt no longer loses it to a
|
|
952
1249
|
refusal. It reads the project first, so a `--project` of another team or
|
|
953
1250
|
of a deleted project fails `404 NOT_FOUND "Project not found."` before the
|
|
@@ -962,6 +1259,9 @@ An `--update-check` you give replaces the default: without
|
|
|
962
1259
|
another. A piped value works as before.
|
|
963
1260
|
- `naro usage` names a project that has moved to another team
|
|
964
1261
|
`Moved to another team <id>`. Before, it read `Deleted project <id>`.
|
|
1262
|
+
- `naro usage` prints `<1%` for a meter that is used but under 1% of its
|
|
1263
|
+
limit (9,056 of 1,000,000 requests). Before, it printed `0%`, as if
|
|
1264
|
+
nothing had been used.
|
|
965
1265
|
- `naro db reset` reads the migration files the way the control plane now
|
|
966
1266
|
runs them: `ALTER TABLE a RENAME TO b` moves `a`'s policies to `b`
|
|
967
1267
|
(known-issues #87), so a policy a renamed table took along is no longer
|
|
@@ -1369,7 +1669,7 @@ not fail but no strategy can ship it, `NO_DEPLOYMENT_STRATEGY`. Either way the m
|
|
|
1369
1669
|
what each strategy failed at.
|
|
1370
1670
|
|
|
1371
1671
|
`--yes` (or `-y`) suppresses every prompt — destructive actions
|
|
1372
|
-
(production rollback
|
|
1672
|
+
(production rollback, promote to production or to an environment, env/domain/environment removal, `naro env import`, turning off an environment's protection, database reset, backend key
|
|
1373
1673
|
rotation, policy removal and drop, opening the preview with
|
|
1374
1674
|
`naro protection disable`, replacing or removing the bypass secret) run
|
|
1375
1675
|
unconfirmed, so use it deliberately in
|
|
@@ -1405,5 +1705,5 @@ credentials live in `~/.naro/credentials.json` (0600).
|
|
|
1405
1705
|
| ------------------------ | ---------------------------------------------- |
|
|
1406
1706
|
| `NARO_TOKEN` | CI/agent access token (skips `naro login`) |
|
|
1407
1707
|
| `NARO_CONTROL_PLANE_URL` | Custom control plane (default https://naro.sh) |
|
|
1408
|
-
| `NARO_SERVICE_KEY` | Service key for `naro storage ls\|cp\|rm`
|
|
1708
|
+
| `NARO_SERVICE_KEY` | Service key for `naro storage ls\|cp\|mv\|rm` |
|
|
1409
1709
|
| `NARO_SUPABASE_URL/KEY` | Auth backend override (self-hosted setups) |
|