diff --git a/contents/docs/custom-mutators.mdx b/contents/docs/custom-mutators.mdx index 2386616..04be0bd 100644 --- a/contents/docs/custom-mutators.mdx +++ b/contents/docs/custom-mutators.mdx @@ -358,24 +358,12 @@ If the client-side mutator fails, the `.server` promise is also rejected with th You will need a server somewhere you can run an endpoint on. This is typically a serverless function on a platform like Vercel or AWS but can really be anything. -Configure the push endpoint with the `push.url` parameter in your `Zero` constructor: - -```ts -const zero = new Zero({ - push: { - url: 'https://zero.my-server.com/push', - }, -}); -``` - -You will also need to enable the server to be used as a push endpoint with the [`ZERO_PUSH_URL` environment variable or `--push-url` flag](./zero-cache-config#push-url): +Configure the push endpoint with the `ZERO_MUTATE_URL` configuration parameter: ```bash -ZERO_PUSH_URL=https://*.my-server.com/push +ZERO_MUTATE_URL=https://my-server.com/api/mutate ``` -The `ZERO_PUSH_URL` parameter accepts wildcards, enabling the client to pass runtime configuration to the push endpoint or to use a different push endpoint, e.g., for previews. See the [config docs](./zero-cache-config#push-url) for the full syntax. - The push endpoint receives a `PushRequest` as input describing one or more mutations to apply to the backend, and must return a `PushResponse` describing the results of those mutations. If you are implementing your server in TypeScript, you can use the `PushProcessor` class to trivially implement this endpoint. Here’s an example in a [Hono](https://hono.dev/) app: @@ -419,6 +407,72 @@ export default handle(app); To reuse the client mutators exactly as-is on the server just pass the result of the same `createMutators` function to `PushProcessor`. +### Custom Mutate URL + +By default, custom mutators use the URL specified in the `ZERO_MUTATE_URL` parameter. However you can customize this on a per-client basis. To do so, list multiple comma-separted URLs in the `ZERO_MUTATE_URL` parameter: + +```bash +ZERO_MUTATE_URL='https://api.example.com/mutate,https://api.staging.example.com/mutate' +``` + +Then choose one of those URLs by passing it to `mutateURL` on the `Zero` constructor: + +```ts +const zero = new Zero({ + schema, + mutators: createMutators(), + mutateURL: 'https://api.staging.example.com/mutate', +}); +``` + +### Wildcards + +The URLs listed in `ZERO_MUTATE_URL` can contain `*` wildcards: + +```bash +# Allow any subdomain of example.com +ZERO_MUTATE_URL="https://*.example.com/push" +``` + +This mutate URL will allow clients to choose URLs like: +- `https://api.example.com/push` ✅ +- `https://staging.example.com/push` ✅ +- `https://api-feat-123.example.com/push` ✅ + +But rejects URLs like: +- `https://example.com/push` ❌ (no subdomain) +- `https://malicious.com/push` ❌ (different domain) +- `https://api.example.com/push/extra` ❌ (extra path) + +Wildcards are only allowed for subdomains and follow these rules: + +**Single Wildcard:** +```bash +ZERO_MUTATE_URL="https://*.example.com/push" +``` +- ✅ Matches: `https://api.example.com/push` +- ✅ Matches: `https://www.example.com/push` +- ✅ Matches: `https://staging-v2.example.com/push` +- ❌ Does not match: `https://example.com/push` (no subdomain) +- ❌ Does not match: `https://api.staging.example.com/push` (multiple subdomains) + +**Multiple Wildcards:** +```bash +ZERO_MUTATE_URL="https://*.*.example.com/push" +``` +- ✅ Matches: `https://api.v1.example.com/push` +- ✅ Matches: `https://www.staging.example.com/push` +- ❌ Does not match: `https://api.example.com/push` (only one subdomain) +- ❌ Does not match: `https://api.v1.staging.example.com/push` (three subdomains) + +**Path Restrictions:** +```bash +ZERO_MUTATE_URL="https://*.example.com/api/push" +``` +- ✅ Matches: `https://api.example.com/api/push` +- ❌ Does not match: `https://api.example.com/api/push/extra` (trailing path) +- ❌ Does not match: `https://api.example.com/push` (missing /api) + ### Server Error Handling The `PushProcessor` in `@rocicorp/zero/pg` skips any mutations that throw: diff --git a/contents/docs/release-notes/0.24.mdx b/contents/docs/release-notes/0.24.mdx new file mode 100644 index 0000000..4d132ba --- /dev/null +++ b/contents/docs/release-notes/0.24.mdx @@ -0,0 +1,24 @@ +--- +title: Zero 0.24 +description: Preview Support +--- + +## Install + +```bash +npm install @rocicorp/zero@0.24 +``` + +## Upgrading + +## Features + +- Preview support for [custom mutators](/docs/custom-mutators#custom-mutate-url) and [synced queries](/docs/synced-queries#custom-get-queries-url). + +## Fixes + +## zbugs + +## Breaking Changes + +- The `push.url` client parameter was removed in favor of `mutateURL`. A matching `ZERO_MUTATE_URL` config param was also added. \ No newline at end of file diff --git a/contents/docs/release-notes/index.mdx b/contents/docs/release-notes/index.mdx index f8ab433..107fba4 100644 --- a/contents/docs/release-notes/index.mdx +++ b/contents/docs/release-notes/index.mdx @@ -2,6 +2,7 @@ title: Release Notes --- +- [Zero 0.24: Preview Support](/docs/release-notes/0.24) - [Zero 0.23: Synced Queries and React Native Support](/docs/release-notes/0.23) - [Zero 0.22: Simplified TTLs](/docs/release-notes/0.22) - [Zero 0.21: PG arrays, TanStack starter, and more](/docs/release-notes/0.21) diff --git a/contents/docs/synced-queries.mdx b/contents/docs/synced-queries.mdx index 67508f8..0cb46fc 100644 --- a/contents/docs/synced-queries.mdx +++ b/contents/docs/synced-queries.mdx @@ -12,7 +12,7 @@ This has many benefits: * No need for a separate permission system. Your server enforces permissions by constructing queries dynamically. Clients have no direct access to the database. * Simpler auth. Your server can use any auth system you want – Zero does not need to know or understand it. -* Previews. Since synced queries are implemented on your server, they can naturally support [branch previews](https://vercel.com/docs/deployments/sharing-deployments) on platforms like Vercel. This [doesn't quite work yet](https://bugs.rocicorp.dev/issue/4063), but will be coming to Zero soon. +* Previews. Since synced queries are implemented on your server, they can naturally support [branch previews](#custom-get-queries-url) on platforms like Vercel. This feature used to be called "custom queries". But soon it will be Zero's only read API, and won't be "custom" at all. So we renamed it. @@ -317,6 +317,30 @@ function getQuery( } ``` +### Custom Get Queries URL + +By default, synced queries use the URL specified in the `ZERO_GET_QUERIES_URL` parameter. However you can customize this on a per-client basis. To do so, list multiple comma-separted URLs in the `ZERO_GET_QUERIES_URL` parameter: + +However you can customize this on a per-client basis. To do so, list multiple comma-separted URLs in the `ZERO_GET_QUERIES_URL` parameter: + +```bash +ZERO_GET_QUERIES_URL='https://api.example.com/get-queries,https://api.staging.example.com/get-queries' +``` + +Then choose one of those URLs by passing it to `getQueriesURL` on the `Zero` constructor: + +```ts +const zero = new Zero({ + schema, + mutators: createMutators(), + getQueriesURL: 'https://api.staging.example.com/get-queries', +}); +``` + +### Wildcards + +The URLs listed in `ZERO_GET_QUERIES_URL` can contain `*` wildcards. See the [Wildcard Syntax](./custom-mutators#wildcard-syntax) section in the Custom Mutators documentation for details. It works the same way for synced queries. + ## Custom Server Implementation It is possible to implement the `ZERO_GET_QUERIES_URL` endpoint without using Zero's TypeScript libraries, or even in a different language entirely.