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.
Files changed (3) hide show
  1. package/README.md +88 -26
  2. package/dist/index.mjs +3221 -2900
  3. 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 the slug each is addressed by | `read:apps` |
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. Nothing gives
549
- an agent billing, a plan change, credential management or your workspace's slug: those are closed to
550
- every credential, whatever it carries.
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. Each carries `Cache-Control: public, max-age=31536000, immutable` and an
627
- `ETag`, so name your build output by content hash. A file's bytes must never change under a name a
628
- browser has already cached for a year. The content type comes from the extension against a fixed
629
- allowlist and is never sniffed; anything off it is served as a download.
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
- - **At most 100 files may sit outside `assets/`.** Those paths travel on the version record so a
636
- request can be routed without a lookup per file. Put bulk output under `assets/`, where a file
637
- costs nothing; `favicon.ico`, `robots.txt` and a `.well-known/` directory are what the rest is
638
- for.
639
-
640
- **HTML is refused at deploy time.** Your Function renders its own markup, and a document served from
641
- your App's own origin is the sharpest same-origin risk a static file carries.
642
-
643
- **An SVG is served inert.** The rule behind the refusal above is that nothing you deploy as a file
644
- becomes a page on your App's own origin, and an SVG opened directly in a browser would become one.
645
- It runs script, and it renders whatever HTML a `<foreignObject>` holds. It is served rather than
646
- refused because making it inert costs the file nothing. An `<img src="logo.svg">` never ran that
647
- script and is never checked against the policy, so your drawings render as they always did. Every
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`, attaches like any other name. Whether a CNAME may sit at
775
- your zone root is your DNS provider's rule, and where it cannot, attach `www.client.com` and configure
776
- the redirect at the provider.
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
- Four headers arrive or leave on it, and the stripping is what makes them worth trusting:
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