wawesome 0.14.3 → 0.16.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 +88 -26
- package/dist/index.mjs +3221 -2900
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,6 +118,7 @@ npx wawesome deploy
|
|
|
118
118
|
| `npx wawesome env set <key> <val>` | Set an environment variable (add `--secret` for write-only) |
|
|
119
119
|
| `npx wawesome env rm <key>` | Delete an environment variable |
|
|
120
120
|
| `npx wawesome domains` | Show the app's domain, its state, and the DNS records to add |
|
|
121
|
+
| `npx wawesome domains adopt` | Write the domain the app answers at into wawesome-function.json |
|
|
121
122
|
| `npx wawesome domains detach <host>` | Stop serving the app at a domain you attached |
|
|
122
123
|
| `npx wawesome credentials` | List deploy credentials: name, prefix, capabilities, Apps, last use |
|
|
123
124
|
| `npx wawesome credentials mint <name>` | Mint a deploy credential and print its secret, once |
|
|
@@ -477,11 +478,13 @@ concluding the platform cannot do it.
|
|
|
477
478
|
|
|
478
479
|
| Tool | What it does | Needs |
|
|
479
480
|
|:---------------------------|:------------------------------------------------------------------------|:--------------|
|
|
481
|
+
| `whoami` | The workspace, where it is administered, the words this credential carries, the Apps it reaches | nothing |
|
|
480
482
|
| `list_templates` | The template catalogue, with what each one is for | nothing |
|
|
481
483
|
| `get_template` | One template's files, environment contract and outbound providers | nothing |
|
|
482
|
-
| `list_apps` | The Apps the credential reaches, with
|
|
484
|
+
| `list_apps` | The Apps the credential reaches, each with its address and its dashboard page | `read:apps` |
|
|
483
485
|
| `list_functions` | The Functions in one App, and what their live version carries | `read:functions` |
|
|
484
486
|
| `list_versions` | A Function's Versions, and which one is live | `read:functions` |
|
|
487
|
+
| `get_function_source` | The code a Function is running, and the static files it carries | `read:functions` |
|
|
485
488
|
| `get_usage` | The Tenant's usage and headroom | `read:tenant` |
|
|
486
489
|
| `list_invocations` | Recent Invocations of a Function, failures included | `read:invocations` |
|
|
487
490
|
| `get_invocation` | One Invocation by id | `read:invocations` |
|
|
@@ -491,11 +494,20 @@ concluding the platform cannot do it.
|
|
|
491
494
|
| `deploy_status` | How a deploy went, by the handle it answered with | `read:functions` |
|
|
492
495
|
| `rollback_function` | Puts a Version the Function already has back on its public address | `write:functions` |
|
|
493
496
|
| `set_env_var` | Sets an App's environment variable, read at the next invocation | `write:env` |
|
|
497
|
+
| `attach_domain` | Attaches a domain to an App and answers the DNS records that make it work | `write:domains` |
|
|
498
|
+
| `cancel_domain_claim` | Gives up a domain claim nobody has proved control of, freeing the App's place | `write:domains` |
|
|
499
|
+
| `check_domain` | Where the domain attached to an App got to, asked at the certificate vendor | `read:domains` |
|
|
494
500
|
| `invoke_function` | Runs a deployed Function once and answers with the Invocation id | `write:runs` |
|
|
501
|
+
| `fetch_function` | Fetches one path from a Function's live Version and answers what it served | `write:runs` |
|
|
495
502
|
|
|
496
503
|
A word that writes reaches the read of the same thing, so `write:functions` needs no `read:functions`
|
|
497
504
|
beside it, and the presets below are named in exactly these words.
|
|
498
505
|
|
|
506
|
+
`whoami` is the one to call first. It answers the workspace, every word the credential carries and
|
|
507
|
+
the Apps it reaches, and it asks for nothing — so your agent can say what it is able to do before it
|
|
508
|
+
offers, rather than finding the edge by being refused in front of you. A member's session calling the
|
|
509
|
+
endpoint gets the same answer for the role they hold.
|
|
510
|
+
|
|
499
511
|
A deploy is two calls. The first says which of your files the platform does not already hold, by
|
|
500
512
|
content hash; your agent uploads those bytes to `PUT /v1/assets/{content_hash}` with the same
|
|
501
513
|
credential and asks again, so a redeploy that changed only its code uploads nothing. The second
|
|
@@ -545,9 +557,13 @@ npx wawesome credentials mint ci --preset deployer -a prod
|
|
|
545
557
|
npx wawesome credentials mint agent --preset member -a prod
|
|
546
558
|
```
|
|
547
559
|
|
|
548
|
-
Add `write:domains` where the project declares a custom domain the deploy should claim
|
|
549
|
-
|
|
550
|
-
|
|
560
|
+
Add `write:domains` where the project declares a custom domain the deploy should claim, or where an
|
|
561
|
+
agent attaches one for somebody who has no terminal — it also gives back a claim nobody has proved
|
|
562
|
+
control of yet, and never takes a live name off an App. Nothing gives
|
|
563
|
+
an agent billing, a plan change, credential management or the ability to rename your workspace: those
|
|
564
|
+
are closed to every credential, whatever it carries. Reading the workspace's name and address is not
|
|
565
|
+
among them — `whoami` answers both to any credential, which is how the agent knows where what it
|
|
566
|
+
deploys will appear.
|
|
551
567
|
|
|
552
568
|
Keep `-a` on all three. A credential restricted to one App is refused on every tool that names
|
|
553
569
|
another, which is what stops an agent working on one client's project from touching another's.
|
|
@@ -602,6 +618,33 @@ URL, serving the code its callers already hold. The CLI remembers where this dir
|
|
|
602
618
|
deployed and asks before that happens, naming both URLs. If you meant it, delete the old Function
|
|
603
619
|
from the dashboard once nothing calls it.
|
|
604
620
|
|
|
621
|
+
### A site with no handler
|
|
622
|
+
|
|
623
|
+
Leave `entry` out, write no `src/index.ts`, and point `"assets"` at the directory your build wrote
|
|
624
|
+
its pages into:
|
|
625
|
+
|
|
626
|
+
```json
|
|
627
|
+
{
|
|
628
|
+
"app": "my-app",
|
|
629
|
+
"function": "root",
|
|
630
|
+
"assets": "dist"
|
|
631
|
+
}
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
That deploys the pages and no code at all, and the site is live at your App's address. Nothing in the
|
|
635
|
+
file declares a kind: a project with a handler is one that has an entry point, and a project with
|
|
636
|
+
both deploys them together and rolls them back together.
|
|
637
|
+
|
|
638
|
+
An `entry` you did name and that is not there is a hard error, so a typo never quietly becomes a site
|
|
639
|
+
with nothing running behind it. Every deploy says which of the two it landed.
|
|
640
|
+
|
|
641
|
+
One thing the deploy will warn you about: everything beneath a Function's address reaches that
|
|
642
|
+
Function, so a page your root Function carries at `about/index.html` is shadowed by a sibling Function
|
|
643
|
+
named `about`. The deploy says so and names both addresses. It refuses nothing — the two Functions are
|
|
644
|
+
versioned independently, and either one may deploy first.
|
|
645
|
+
|
|
646
|
+
### Static files
|
|
647
|
+
|
|
605
648
|
Add `"assets"` to deploy static files beside your code:
|
|
606
649
|
|
|
607
650
|
```json
|
|
@@ -623,28 +666,32 @@ Files are served straight from object storage; your Function is never invoked fo
|
|
|
623
666
|
invocation is recorded. They answer on your App's own hostname and nowhere else. On the
|
|
624
667
|
development path form (`/x/<tenant>/<app>/<function>/...`) the same address reaches your handler
|
|
625
668
|
as it always has, because a file on an origin every workspace shares would be same-origin with
|
|
626
|
-
all of them.
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
669
|
+
all of them. A file beneath `assets/` carries `Cache-Control: public, max-age=31536000, immutable`,
|
|
670
|
+
so name your build output by content hash: its bytes must never change under a name a browser has
|
|
671
|
+
already cached for a year. A file outside `assets/` keeps one name across every deploy, so it carries
|
|
672
|
+
`max-age=300` instead — five minutes is inside the reach of a deploy and of a rollback, which a year
|
|
673
|
+
is not. The content type comes from the extension against a fixed allowlist and is never sniffed;
|
|
674
|
+
anything off it is served as a download.
|
|
630
675
|
|
|
631
676
|
Two rules to know about:
|
|
632
677
|
|
|
633
678
|
- **Everything beneath `assets/` is static**, whatever the deploy carries. A request there never
|
|
634
679
|
reaches your handler, and an unknown path under it is a 404 rather than a route for you to answer.
|
|
635
|
-
- **
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
680
|
+
- **A file outside `assets/` answers at its own name**, however many of them a deploy carries.
|
|
681
|
+
`favicon.ico`, `robots.txt` and a `.well-known/` directory are what that is for; hashed build
|
|
682
|
+
output belongs under `assets/`.
|
|
683
|
+
|
|
684
|
+
**A page is a file like any other.** An `index.html` your build wrote is deployed, hashed, retained
|
|
685
|
+
and billed exactly as your other files are, and it is what a directory-style address resolves to: a
|
|
686
|
+
path whose last segment carries no extension is served the `index.html` beneath it, so `/`, `/about`,
|
|
687
|
+
`/about/` and `/blog/hello` each answer with a page. A page revalidates rather than being pinned for a
|
|
688
|
+
year, wherever it sits, so deploying and refreshing is a loop that works.
|
|
689
|
+
|
|
690
|
+
**An SVG is served inert.** Nothing you deploy as a resource should be able to run script on your
|
|
691
|
+
App's own origin, and an SVG opened directly in a browser can: it runs script, and it renders whatever
|
|
692
|
+
HTML a `<foreignObject>` holds. It is served rather than refused because making it inert costs the
|
|
693
|
+
file nothing. An `<img src="logo.svg">` never ran that script and is never checked against the
|
|
694
|
+
policy, so your drawings render as they always did. Every
|
|
648
695
|
SVG and XML file carries `Content-Security-Policy: script-src 'none'; sandbox`, and only navigating
|
|
649
696
|
straight to one loses anything. Such a file is sandboxed onto an origin of its own, so its links no
|
|
650
697
|
longer navigate and a page embedding it through `<object>` or `<iframe>` cannot reach into its DOM.
|
|
@@ -771,13 +818,27 @@ deploy prints the refusal and lands everything else it was doing.
|
|
|
771
818
|
The address derived from your workspace slug keeps serving after you attach a domain. Both names
|
|
772
819
|
answer, so webhooks and integrations already pointed at the old one keep working.
|
|
773
820
|
|
|
774
|
-
An apex domain, `client.com` with no `www`,
|
|
775
|
-
|
|
776
|
-
|
|
821
|
+
An apex domain, `client.com` with no `www`, claims `www.client.com` with it, and attaching the `www`
|
|
822
|
+
claims the apex. Both halves are one domain against your App's one place, and both are printed with
|
|
823
|
+
their own state and their own records, because a visitor typing either one should reach your site.
|
|
824
|
+
Where your DNS provider cannot hold a CNAME at your zone root, that half is reported as not claimed
|
|
825
|
+
with the reason, and attaching the same name again picks it up once your DNS can carry it.
|
|
826
|
+
|
|
827
|
+
The file is not the only door. A domain can also be attached from the dashboard or by an agent, and
|
|
828
|
+
then your App answers at a name `wawesome-function.json` has never heard of. A deploy says so and
|
|
829
|
+
edits nothing — what was committed is what ships — so the file is written by a command of your own:
|
|
830
|
+
|
|
831
|
+
```bash
|
|
832
|
+
npx wawesome domains adopt
|
|
833
|
+
```
|
|
834
|
+
|
|
835
|
+
It writes the attached hostname into `wawesome-function.json` and changes nothing about the domain.
|
|
836
|
+
Where the file already declares a *different* name, it refuses and prints both: an App carries one
|
|
837
|
+
domain, and which of the two names it should be is yours to settle rather than a file to overwrite.
|
|
777
838
|
|
|
778
839
|
Deleting the line detaches nothing. Detaching takes a live site dark, which is not something a
|
|
779
840
|
deploy should infer from a deleted line. So the deploy reports the domain it found and left serving,
|
|
780
|
-
and names the one command that takes it off:
|
|
841
|
+
names the command that writes it into the file, and names the one command that takes it off:
|
|
781
842
|
|
|
782
843
|
```bash
|
|
783
844
|
npx wawesome domains detach shop.client.com
|
|
@@ -796,7 +857,7 @@ handler sees it, and off your response before the caller does. So **do not name
|
|
|
796
857
|
own on that prefix**. It is dropped silently rather than rejected, and you will not get an error
|
|
797
858
|
telling you why it vanished.
|
|
798
859
|
|
|
799
|
-
|
|
860
|
+
Five headers arrive or leave on it, and the stripping is what makes them worth trusting:
|
|
800
861
|
|
|
801
862
|
| Header | Direction | What it means |
|
|
802
863
|
| --- | --- | --- |
|
|
@@ -804,6 +865,7 @@ Four headers arrive or leave on it, and the stripping is what makes them worth t
|
|
|
804
865
|
| `x-wawesome-trigger` | inbound | How this run started: `caller` when someone called your address, `schedule` when fired by a Schedule. A caller cannot forge it in production (stripped inbound). On the local development surface, pass `x-wawesome-trigger: schedule` to exercise a background run by hand with the collapsed budget. |
|
|
805
866
|
| `x-wawesome-invocation-id` | outbound | The id of this run, the key to fetch its logs with `npx wawesome logs --invocation <id>`. |
|
|
806
867
|
| `x-wawesome-error` | outbound | Present only when the platform failed, never when your Function did. Its *absence* means the status on the wire is yours, up to the moment your response is committed and no further. |
|
|
868
|
+
| `x-wawesome-document` | outbound | Set it to the path of a document your own deploy carried (`index.html`) and the platform streams that file in place of the body you returned. Your status and your other headers stand; the content type and the length are the file's. Naming a path your deploy does not carry is a `500`, and your logs say which path you named. |
|
|
807
869
|
|
|
808
870
|
### Testing against the guest's JavaScript surface
|
|
809
871
|
|