@fitzzero/quickdraw-core 5.0.0-rc.7 → 5.0.1
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 +58 -36
- package/dist/{admin-CsXR7Zwy.d.ts → admin-CBlTY0do.d.ts} +24 -9
- package/dist/{adminSchemas-Dufu8r7a.d.ts → adminSchemas-zji11V74.d.ts} +15 -9
- package/dist/{caller-N1zmIB8c.d.ts → caller-BqCYnpmC.d.ts} +2 -2
- package/dist/{chunk-6FFNAT7S.js → chunk-2XJFNVHW.js} +2 -2
- package/dist/chunk-2XJFNVHW.js.map +1 -0
- package/dist/{chunk-FMOLH6PL.js → chunk-3JNMVB2V.js} +3 -3
- package/dist/{chunk-RLEHORXX.js → chunk-4DIQHASK.js} +3 -3
- package/dist/chunk-4DIQHASK.js.map +1 -0
- package/dist/{chunk-V3KNCTXJ.js → chunk-4YO5H5ON.js} +1 -1
- package/dist/chunk-4YO5H5ON.js.map +1 -0
- package/dist/{chunk-3I7R3DZW.js → chunk-5YRQ26LF.js} +1 -1
- package/dist/chunk-5YRQ26LF.js.map +1 -0
- package/dist/{chunk-6G663RIR.js → chunk-B2P7AZ25.js} +3 -3
- package/dist/chunk-B2P7AZ25.js.map +1 -0
- package/dist/{chunk-NKVWV3FL.js → chunk-CDKG4TFA.js} +25 -5
- package/dist/chunk-CDKG4TFA.js.map +1 -0
- package/dist/{chunk-XPTZFIWZ.js → chunk-DD4SKCNO.js} +2 -2
- package/dist/chunk-DD4SKCNO.js.map +1 -0
- package/dist/{chunk-7N6GOASM.js → chunk-HQ6WIRE2.js} +5 -5
- package/dist/chunk-HQ6WIRE2.js.map +1 -0
- package/dist/{chunk-X7T25LME.js → chunk-NS5PUHIZ.js} +289 -28
- package/dist/chunk-NS5PUHIZ.js.map +1 -0
- package/dist/{chunk-BXN7CACY.js → chunk-O2PWC2YW.js} +7 -7
- package/dist/chunk-O2PWC2YW.js.map +1 -0
- package/dist/{chunk-FMEHXFPL.js → chunk-QEKVYG5F.js} +2 -2
- package/dist/chunk-QEKVYG5F.js.map +1 -0
- package/dist/{chunk-X2YCUIEK.js → chunk-REX5YPHX.js} +2 -2
- package/dist/chunk-REX5YPHX.js.map +1 -0
- package/dist/{chunk-DEXRBC5F.js → chunk-WVIRXYI4.js} +3 -3
- package/dist/chunk-WVIRXYI4.js.map +1 -0
- package/dist/{chunk-KR7K4QEY.js → chunk-X5CWPX7H.js} +1 -1
- package/dist/chunk-X5CWPX7H.js.map +1 -0
- package/dist/{chunk-G47OHQYB.js → chunk-YSWH776Y.js} +1 -1
- package/dist/chunk-YSWH776Y.js.map +1 -0
- package/dist/{chunk-3OYVPO4L.js → chunk-ZACRRYWL.js} +6 -6
- package/dist/chunk-ZACRRYWL.js.map +1 -0
- package/dist/cli/quickdraw-docs.js +1 -1
- package/dist/client/index.d.ts +3 -3
- package/dist/client/index.js +9 -9
- package/dist/client/index.js.map +1 -1
- package/dist/{clientTypes-rfpWR8yz.d.ts → clientTypes-DuZW_8mb.d.ts} +1 -1
- package/dist/{createServer-BxcXQlk8.d.ts → createServer-CGsJlxM8.d.ts} +2 -2
- package/dist/{createTestApp-CY-RpwCu.d.ts → createTestApp-Cg2CZa1g.d.ts} +3 -3
- package/dist/{http-DywMt0Yf.d.ts → http-D3fSFQ57.d.ts} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/prisma/index.d.ts +1 -1
- package/dist/prisma/index.js +4 -4
- package/dist/prisma/index.js.map +1 -1
- package/dist/server/auth/index.d.ts +11 -2
- package/dist/server/auth/index.js +3 -8
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/index.d.ts +84 -18
- package/dist/server/index.js +94 -167
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/index.d.ts +2 -2
- package/dist/server/mcp/index.js +5 -5
- package/dist/server/mcp/index.js.map +1 -1
- package/dist/{sharing-BSTPqvgD.d.ts → sharing-CoreezAq.d.ts} +2 -2
- package/dist/testing/client.d.ts +7 -7
- package/dist/testing/client.js +9 -9
- package/dist/testing/client.js.map +1 -1
- package/dist/testing/index.d.ts +6 -6
- package/dist/testing/index.js +9 -9
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/mock.d.ts +3 -3
- package/dist/testing/mock.js +8 -8
- package/dist/utils/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-3I7R3DZW.js.map +0 -1
- package/dist/chunk-3OYVPO4L.js.map +0 -1
- package/dist/chunk-6FFNAT7S.js.map +0 -1
- package/dist/chunk-6G663RIR.js.map +0 -1
- package/dist/chunk-7N6GOASM.js.map +0 -1
- package/dist/chunk-BXN7CACY.js.map +0 -1
- package/dist/chunk-DEXRBC5F.js.map +0 -1
- package/dist/chunk-FMEHXFPL.js.map +0 -1
- package/dist/chunk-G47OHQYB.js.map +0 -1
- package/dist/chunk-KR7K4QEY.js.map +0 -1
- package/dist/chunk-NKVWV3FL.js.map +0 -1
- package/dist/chunk-RLEHORXX.js.map +0 -1
- package/dist/chunk-V3KNCTXJ.js.map +0 -1
- package/dist/chunk-X2YCUIEK.js.map +0 -1
- package/dist/chunk-X7T25LME.js.map +0 -1
- package/dist/chunk-XPTZFIWZ.js.map +0 -1
- /package/dist/{chunk-FMOLH6PL.js.map → chunk-3JNMVB2V.js.map} +0 -0
package/README.md
CHANGED
|
@@ -25,20 +25,19 @@ single hand-written event.
|
|
|
25
25
|
- **Testing**: a real test server, access matrices, performance budgets that
|
|
26
26
|
count statements and bytes, strict development warnings.
|
|
27
27
|
|
|
28
|
-
Design record: [`docs/rfcs/0003-v5.md`](https://github.com/fitzzero/quickdraw/blob/
|
|
28
|
+
Design record: [`docs/rfcs/0003-v5.md`](https://github.com/fitzzero/quickdraw/blob/main/docs/rfcs/0003-v5.md).
|
|
29
29
|
|
|
30
30
|
## Install
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
bun add @fitzzero/quickdraw-core
|
|
33
|
+
bun add @fitzzero/quickdraw-core zod
|
|
34
34
|
bun add express socket.io @prisma/client # the server
|
|
35
35
|
bun add socket.io-client @tanstack/react-query react # the web app
|
|
36
|
-
bun add -d @fitzzero/quickdraw-lint
|
|
36
|
+
bun add -d @fitzzero/quickdraw-lint @fitzzero/quickdraw-skills oxlint
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
peer dependency is optional: install the ones the entries you import need.
|
|
39
|
+
Node 24 or later. Every peer dependency is optional: install the ones the
|
|
40
|
+
entries you import need.
|
|
42
41
|
|
|
43
42
|
| Entry | Needs |
|
|
44
43
|
| --------------------------------------- | ----------------------------------------------------------------------- |
|
|
@@ -59,7 +58,7 @@ peer dependency is optional: install the ones the entries you import need.
|
|
|
59
58
|
A board of tasks in the quickdraw template's layout: contracts in
|
|
60
59
|
`packages/shared`, the server in `apps/api`, the web app in `apps/web`. The
|
|
61
60
|
examples in this README compile: they are copies of
|
|
62
|
-
[`packages/core/test/readme/`](https://github.com/fitzzero/quickdraw/tree/
|
|
61
|
+
[`packages/core/test/readme/`](https://github.com/fitzzero/quickdraw/tree/main/packages/core/test/readme),
|
|
63
62
|
which the package's typecheck builds. The pieces the quick start imports
|
|
64
63
|
without showing (the schemas, the auth helpers, the Prisma models) are under
|
|
65
64
|
[The example app](#the-example-app).
|
|
@@ -319,7 +318,7 @@ and `countOnBoard` is fetched again because it watches the board.
|
|
|
319
318
|
|
|
320
319
|
The quick start is part of a small app in the template's layout, whose
|
|
321
320
|
every file compiles with the package:
|
|
322
|
-
[`packages/core/test/readme/`](https://github.com/fitzzero/quickdraw/tree/
|
|
321
|
+
[`packages/core/test/readme/`](https://github.com/fitzzero/quickdraw/tree/main/packages/core/test/readme).
|
|
323
322
|
The label and project services the server registers are there, with the
|
|
324
323
|
other sections' examples. These are the pieces the quick start imports
|
|
325
324
|
without showing, which an app writes itself.
|
|
@@ -735,16 +734,23 @@ export const taskService = qd.defineService(task, {
|
|
|
735
734
|
(`qd:access`), and in-process callers load the grants again.
|
|
736
735
|
- Policies: `owner(field)`, `jsonAcl(field, { owner? })`,
|
|
737
736
|
`members({ model, entry, user, level, levels? })`, `inherit({ from, via })`,
|
|
738
|
-
`anyOf(...)`, `resolver({ levelsFor, where
|
|
737
|
+
`anyOf(...)`, `resolver({ levelsFor, where?, reads })` and `everyone(level)`
|
|
739
738
|
(every signed-in user has `level` on every row, reading nothing: public
|
|
740
739
|
profiles are `anyOf(owner("id"), everyone("Read"))`; unlike `rowless: true`
|
|
741
|
-
on a method, it covers subscriptions and lists too).
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
740
|
+
on a method, it covers subscriptions and lists too). A `resolver` is app
|
|
741
|
+
code, so it says what its levels depend on: `reads: { columns, memberships }`
|
|
742
|
+
names columns of the service's model and membership tables as `members`
|
|
743
|
+
takes them (`entry` holding this service's row id), and tracked writes to
|
|
744
|
+
them re-check what it decided, as for the other policies; `reads: "none"`
|
|
745
|
+
says nothing a tracked write changes can change a level (the principal's
|
|
746
|
+
grants alone, say). A resolver with neither is never re-checked, and the
|
|
747
|
+
server warns `[quickdraw:resolver-without-reads]` when it starts. Their
|
|
748
|
+
column and table names are checked against the Prisma client's models at
|
|
749
|
+
compile time. A lookup is one batched query per table, memoized for the
|
|
750
|
+
call, so checking 60 ids costs what checking one does. `entry` access
|
|
751
|
+
needs a policy; a service without `model` may only use `"public"`,
|
|
752
|
+
`"authenticated"`, `{ service }` and `custom`. `inherit` uses the
|
|
753
|
+
parent's policy only: grants on the parent's service do not flow down.
|
|
748
754
|
- One policy decides every surface: method calls, entity subscriptions,
|
|
749
755
|
collection scopes, the kits' lists and searches, streams and channels.
|
|
750
756
|
- When a tracked write lowers or removes someone's access, their sockets
|
|
@@ -957,7 +963,7 @@ export const taskService = qd.defineService(task, {
|
|
|
957
963
|
Valkey's clock in microseconds, so revisions from all nodes are one order;
|
|
958
964
|
its key needs persistence or replication. A node whose Valkey connection
|
|
959
965
|
comes back has its clients reconnect to catch up.
|
|
960
|
-
[docs/deploying.md](https://github.com/fitzzero/quickdraw/blob/
|
|
966
|
+
[docs/deploying.md](https://github.com/fitzzero/quickdraw/blob/main/docs/deploying.md) has the wiring, what holds across
|
|
961
967
|
nodes, what it costs, and what happens when a node or Valkey stops
|
|
962
968
|
answering.
|
|
963
969
|
|
|
@@ -1483,9 +1489,9 @@ such code, and `createInvalidationCoordinator(queryClient)` invalidates as
|
|
|
1483
1489
|
the hooks do.
|
|
1484
1490
|
|
|
1485
1491
|
A client in another language (a Godot game, a native app) speaks the wire
|
|
1486
|
-
itself: [`docs/protocol-v5.md`](https://github.com/fitzzero/quickdraw/blob/
|
|
1487
|
-
generated from the protocol's source, and [`examples/godot`](https://github.com/fitzzero/quickdraw/tree/
|
|
1488
|
-
holds a GDScript client written from it. [`docs/clients.md`](https://github.com/fitzzero/quickdraw/blob/
|
|
1492
|
+
itself: [`docs/protocol-v5.md`](https://github.com/fitzzero/quickdraw/blob/main/docs/protocol-v5.md) is its specification,
|
|
1493
|
+
generated from the protocol's source, and [`examples/godot`](https://github.com/fitzzero/quickdraw/tree/main/examples/godot)
|
|
1494
|
+
holds a GDScript client written from it. [`docs/clients.md`](https://github.com/fitzzero/quickdraw/blob/main/docs/clients.md)
|
|
1489
1495
|
compares the three ways in.
|
|
1490
1496
|
|
|
1491
1497
|
## Kits
|
|
@@ -1949,6 +1955,8 @@ export const taskService = qd.defineService(task, {
|
|
|
1949
1955
|
displayName: "Tasks",
|
|
1950
1956
|
// never shown, returned or written
|
|
1951
1957
|
hiddenFields: ["notes"],
|
|
1958
|
+
// the only fields adminCreate and adminUpdate write; the rest are read-only
|
|
1959
|
+
editable: ["title", "status"],
|
|
1952
1960
|
fieldOverrides: { assigneeId: { type: "relation", relationService: "userService" } },
|
|
1953
1961
|
}),
|
|
1954
1962
|
},
|
|
@@ -2006,12 +2014,24 @@ export function AdminTasks() {
|
|
|
2006
2014
|
`adminUpdate({ id, data })` write the entity's fields through the tracked
|
|
2007
2015
|
client, so subscribers and collections get the same frames as for any
|
|
2008
2016
|
other write; `adminDelete({ id })` returns `null`. `id`, `createdAt` and
|
|
2009
|
-
`updatedAt` are never writable, nor are hidden fields
|
|
2010
|
-
made read-only (`VALIDATION`); without a
|
|
2011
|
-
are the columns the policy reads, and a
|
|
2012
|
-
with the row level on it (`FORBIDDEN`,
|
|
2013
|
-
value is checked by the entity schema
|
|
2014
|
-
refuses is `VALIDATION`. A missing row
|
|
2017
|
+
`updatedAt` are never writable, nor are hidden fields, those an override
|
|
2018
|
+
made read-only or those `editable` leaves out (`VALIDATION`); without a
|
|
2019
|
+
service-wide `Admin` grant, nor are the columns the policy reads, and a
|
|
2020
|
+
row moves to another parent only with the row level on it (`FORBIDDEN`,
|
|
2021
|
+
as for the read/write kit); each value is checked by the entity schema
|
|
2022
|
+
itself, and a value the database refuses is `VALIDATION`. A missing row
|
|
2023
|
+
is `NOT_FOUND`.
|
|
2024
|
+
- `editable: ["title", "status"]` names the only fields `adminCreate` and
|
|
2025
|
+
`adminUpdate` write: `adminMeta` reports every other field
|
|
2026
|
+
`editable: false`, so a generic form leaves it read-only, and a write
|
|
2027
|
+
naming one is `VALIDATION` ("is not editable"). Each must be a field the
|
|
2028
|
+
kit shows, never `id` or a timestamp, and a `fieldOverrides` entry may
|
|
2029
|
+
not say otherwise. `admin.contract({ entity, editable })` takes the same
|
|
2030
|
+
list, so the writes' input checks, types and JSON Schema (and the MCP
|
|
2031
|
+
tools made from it) name only those fields; given to both halves, the
|
|
2032
|
+
two lists must name the same fields. Without either list the kit writes
|
|
2033
|
+
what it wrote in 5.0.0: every field it shows but `id` and the timestamps,
|
|
2034
|
+
less those an override made read-only.
|
|
2015
2035
|
- `adminMeta()` returns `{ serviceName, displayName, fields }`, one
|
|
2016
2036
|
`{ name, type, label, required, editable, showInTable, sortable, filterable, enumValues?, relationService?, kind?, showInForm? }`
|
|
2017
2037
|
per field: `type` is
|
|
@@ -2857,6 +2877,7 @@ one format and names the method call it happened in:
|
|
|
2857
2877
|
| `batch-create-many` | a `createMany` in an array-form `$transaction` could not report its rows |
|
|
2858
2878
|
| `repeated-call` | one connection repeated a call or was refused `RATE_LIMITED` again and again (below) |
|
|
2859
2879
|
| `tiered-field-in-output` | a method's own output schema declares a field the contract tiers, which only projection outputs strip; raised when the server is made (for an output without JSON Schema, when a reply carries it) |
|
|
2880
|
+
| `resolver-without-reads` | a service's policy is, or combines in `anyOf`, a `resolver` without `reads`, so no tracked write re-checks it; raised when the server is made |
|
|
2860
2881
|
|
|
2861
2882
|
Updates and deletes by id inside an interactive transaction are not counted
|
|
2862
2883
|
toward `n-plus-one`: that is how per-row writes are written (see tracked
|
|
@@ -2874,9 +2895,10 @@ fails: the call it happened in fails with `INTERNAL` and the error as its
|
|
|
2874
2895
|
once the reply was recorded (over a socket or HTTP the reply was already
|
|
2875
2896
|
sent, so that error is logged, not thrown). Strictness belongs to the app:
|
|
2876
2897
|
warnings outside its calls (an ambient write while seeding, another app's
|
|
2877
|
-
calls) are logged as usual, and `app.close()` ends it. The
|
|
2878
|
-
the app is made, `tiered-field-in-output
|
|
2879
|
-
itself, so a strict app over such a method
|
|
2898
|
+
calls) are logged as usual, and `app.close()` ends it. The ones raised when
|
|
2899
|
+
the app is made, `tiered-field-in-output` and `resolver-without-reads`, are
|
|
2900
|
+
thrown from `createTestApp` itself, so a strict app over such a method or
|
|
2901
|
+
policy does not start.
|
|
2880
2902
|
|
|
2881
2903
|
A `repeated-call` warning names a client caught in a loop (a mutation fired
|
|
2882
2904
|
from an effect that its own result runs again, a refetch that triggers
|
|
@@ -3103,7 +3125,7 @@ nothing. Run `--check` in CI next to the lint step.
|
|
|
3103
3125
|
|
|
3104
3126
|
## Lint rules and agent guidance
|
|
3105
3127
|
|
|
3106
|
-
[`@fitzzero/quickdraw-lint`](https://github.com/fitzzero/quickdraw/tree/
|
|
3128
|
+
[`@fitzzero/quickdraw-lint`](https://github.com/fitzzero/quickdraw/tree/main/packages/lint) is the oxlint plugin and base
|
|
3107
3129
|
config every 5.0 app extends: it reports untracked and foreign writes, nested
|
|
3108
3130
|
and raw SQL writes, hand-sent frames, inline auth guards, unbounded reads,
|
|
3109
3131
|
database calls and emits in loops, layering breaks, bypasses of the typed
|
|
@@ -3118,7 +3140,7 @@ takes an `id`, unless it says `rowless: true`); then lint; then a
|
|
|
3118
3140
|
development warning as it happens (`repeated-call`, `repeated-mutation` and
|
|
3119
3141
|
`repeated-invalidation` name a client loop before the rate limit does).
|
|
3120
3142
|
|
|
3121
|
-
[`@fitzzero/quickdraw-skills`](https://github.com/fitzzero/quickdraw/tree/
|
|
3143
|
+
[`@fitzzero/quickdraw-skills`](https://github.com/fitzzero/quickdraw/tree/main/packages/skills) ships agent rules and skills
|
|
3122
3144
|
for quickdraw apps and links them into `.claude/` with
|
|
3123
3145
|
`quickdraw-skills link`, so every app's agents read the same, current
|
|
3124
3146
|
guidance:
|
|
@@ -3134,17 +3156,17 @@ guidance:
|
|
|
3134
3156
|
|
|
3135
3157
|
## Migrating from 4.x
|
|
3136
3158
|
|
|
3137
|
-
[`@fitzzero/quickdraw-codemod`](https://github.com/fitzzero/quickdraw/tree/
|
|
3159
|
+
[`@fitzzero/quickdraw-codemod`](https://github.com/fitzzero/quickdraw/tree/main/packages/codemod) moves a 4.x app to 5.0:
|
|
3138
3160
|
contracts from the method maps, `defineService` from the service classes,
|
|
3139
3161
|
the typed client for the hooks, and a report of everything left to decide.
|
|
3140
|
-
[`MIGRATION.md`](https://github.com/fitzzero/quickdraw/blob/
|
|
3141
|
-
the defaults that changed; [`UPGRADE-PROMPT.md`](https://github.com/fitzzero/quickdraw/blob/
|
|
3162
|
+
[`MIGRATION.md`](https://github.com/fitzzero/quickdraw/blob/main/MIGRATION.md) explains each step, the access mapping and
|
|
3163
|
+
the defaults that changed; [`UPGRADE-PROMPT.md`](https://github.com/fitzzero/quickdraw/blob/main/UPGRADE-PROMPT.md) is the
|
|
3142
3164
|
procedure for an agent. Both ship with the codemod, at
|
|
3143
3165
|
`node_modules/@fitzzero/quickdraw-codemod/MIGRATION.md` and
|
|
3144
3166
|
`node_modules/@fitzzero/quickdraw-codemod/UPGRADE-PROMPT.md`.
|
|
3145
3167
|
|
|
3146
3168
|
```bash
|
|
3147
|
-
bunx @fitzzero/quickdraw-codemod
|
|
3169
|
+
bunx @fitzzero/quickdraw-codemod v5 .
|
|
3148
3170
|
```
|
|
3149
3171
|
|
|
3150
3172
|
## Package exports
|
|
@@ -3172,7 +3194,7 @@ The package also ships the `quickdraw-docs` command.
|
|
|
3172
3194
|
|
|
3173
3195
|
A bun workspace with turbo: `packages/core` (this package), `packages/lint`,
|
|
3174
3196
|
`packages/skills` and `packages/codemod`. See
|
|
3175
|
-
[CONTRIBUTING.md](https://github.com/fitzzero/quickdraw/blob/
|
|
3197
|
+
[CONTRIBUTING.md](https://github.com/fitzzero/quickdraw/blob/main/CONTRIBUTING.md).
|
|
3176
3198
|
|
|
3177
3199
|
```bash
|
|
3178
3200
|
bun install
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { e as StandardSchemaWithJSON, d as StandardSchemaV1, I as InferInput, c as InferOutput, X as RowSchema, Q as QueryDef, P as ProjectionList, p as MutationDef, J as AnyContract, ap as MethodName } from './infer-Dw21kmLw.js';
|
|
2
|
-
import { d as ListSort, c as ListQuery, b as ListPage, u as AdminListInput, v as AdminListQuery, y as AdminPage, r as AdminCreateInput, s as AdminCreateQuery, B as AdminUpdateInput, C as AdminUpdateQuery, w as AdminMetaInput, n as AdminServiceMeta, z as AdminSubscribers } from './adminSchemas-
|
|
2
|
+
import { d as ListSort, c as ListQuery, b as ListPage, D as AdminWritable, u as AdminListInput, v as AdminListQuery, y as AdminPage, r as AdminCreateInput, s as AdminCreateQuery, B as AdminUpdateInput, C as AdminUpdateQuery, w as AdminMetaInput, n as AdminServiceMeta, z as AdminSubscribers } from './adminSchemas-zji11V74.js';
|
|
3
3
|
|
|
4
4
|
/** A schema a kit generates: validation, and its JSON Schema. */
|
|
5
5
|
type KitSchema<Input, Output = Input> = StandardSchemaWithJSON<Input, Output>;
|
|
@@ -214,6 +214,13 @@ interface AdminContractOptions {
|
|
|
214
214
|
readonly filter?: readonly string[];
|
|
215
215
|
/** The fields `adminList` may sort by; the first is the default order (else `id`). */
|
|
216
216
|
readonly sort?: readonly string[];
|
|
217
|
+
/**
|
|
218
|
+
* The only fields `adminCreate` and `adminUpdate` take (never `id` or a
|
|
219
|
+
* timestamp): their input checks, JSON Schema and types name just these,
|
|
220
|
+
* and the server half writes just these. Without it, every field but `id`
|
|
221
|
+
* and the timestamps. `admin.handlers` given a list too must give the same.
|
|
222
|
+
*/
|
|
223
|
+
readonly editable?: readonly string[];
|
|
217
224
|
/** The methods to add; all eight when absent. */
|
|
218
225
|
readonly expose?: readonly AdminMethodName[];
|
|
219
226
|
/** Descriptions for people and agents, per method; the kit's own for the rest. */
|
|
@@ -223,21 +230,25 @@ interface AdminContractOptions {
|
|
|
223
230
|
}
|
|
224
231
|
type RowOf<Entity> = Entity extends StandardSchemaV1 ? InferOutput<Entity> : never;
|
|
225
232
|
type Quoted<Names> = `"${Names & string}"`;
|
|
226
|
-
type FieldsIn<O, Key extends "filter" | "sort"> = O extends {
|
|
233
|
+
type FieldsIn<O, Key extends "filter" | "sort" | "editable"> = O extends {
|
|
227
234
|
readonly [K in Key]: readonly (infer Field extends string)[];
|
|
228
235
|
} ? Field : never;
|
|
229
236
|
/** A broken option becomes a message: replacing the whole option keeps TypeScript from printing `never`. */
|
|
230
237
|
type Problem<Option extends "filter" | "sort", Wrong> = [Wrong] extends [never] ? unknown : {
|
|
231
238
|
readonly [K in Option]: `admin.contract: ${Option}: ${Quoted<Wrong>} is not a field of the entity holding strings, numbers or booleans`;
|
|
232
239
|
};
|
|
233
|
-
/**
|
|
240
|
+
/** `editable` naming a field the kit never writes, as a message. */
|
|
241
|
+
type EditableProblem<Wrong> = [Wrong] extends [never] ? unknown : {
|
|
242
|
+
readonly editable: `admin.contract: editable: ${Quoted<Wrong>} is not a field of the entity the kit may write`;
|
|
243
|
+
};
|
|
244
|
+
/** The check of `filter`, `sort` and `editable` against the entity that the option types alone cannot state. */
|
|
234
245
|
type AdminChecks<O> = O extends {
|
|
235
246
|
readonly entity: infer Entity;
|
|
236
|
-
} ? Problem<"filter", Exclude<FieldsIn<O, "filter">, ScalarFieldOf<RowOf<Entity>>>> & Problem<"sort", Exclude<FieldsIn<O, "sort">, ScalarFieldOf<RowOf<Entity>>>> : unknown;
|
|
247
|
+
} ? Problem<"filter", Exclude<FieldsIn<O, "filter">, ScalarFieldOf<RowOf<Entity>>>> & Problem<"sort", Exclude<FieldsIn<O, "sort">, ScalarFieldOf<RowOf<Entity>>>> & EditableProblem<Exclude<FieldsIn<O, "editable">, AdminWritable<RowOf<Entity>>>> : unknown;
|
|
237
248
|
type AdminListDef<Row, Filter extends string, Sort extends string> = QueryDef<KitSchema<AdminListInput<Row, Filter, Sort> | undefined, AdminListQuery<Filter, Sort>>, KitSchema<AdminPage<Row>>> & AdminTag<"adminList">;
|
|
238
249
|
type AdminGetDef<Row> = QueryDef<KitSchema<IdInput>, KitSchema<Row>> & AdminTag<"adminGet">;
|
|
239
|
-
type AdminCreateDef<Row
|
|
240
|
-
type AdminUpdateDef<Row
|
|
250
|
+
type AdminCreateDef<Row, Field extends PropertyKey = AdminWritable<Row>> = MutationDef<KitSchema<AdminCreateInput<Row, Field>, AdminCreateQuery>, KitSchema<Row>> & AdminTag<"adminCreate">;
|
|
251
|
+
type AdminUpdateDef<Row, Field extends PropertyKey = AdminWritable<Row>> = MutationDef<KitSchema<AdminUpdateInput<Row, Field>, AdminUpdateQuery>, KitSchema<Row>> & AdminTag<"adminUpdate">;
|
|
241
252
|
type AdminDeleteDef = MutationDef<KitSchema<IdInput>, KitSchema<null>> & AdminTag<"adminDelete">;
|
|
242
253
|
type AdminMetaDef = QueryDef<KitSchema<AdminMetaInput | undefined, undefined>, KitSchema<AdminServiceMeta>> & AdminTag<"adminMeta">;
|
|
243
254
|
type AdminSubscribersDef = QueryDef<KitSchema<IdInput>, KitSchema<AdminSubscribers>> & AdminTag<"adminSubscribers">;
|
|
@@ -245,11 +256,15 @@ type AdminReemitDef = MutationDef<KitSchema<IdInput>, KitSchema<AdminSubscribers
|
|
|
245
256
|
type EntityRowIn<O> = O extends {
|
|
246
257
|
readonly entity: infer Entity;
|
|
247
258
|
} ? RowOf<Entity> : never;
|
|
259
|
+
/** The fields the writes take: those `editable` names, else every field but `id` and the timestamps. */
|
|
260
|
+
type EditableIn<O> = O extends {
|
|
261
|
+
readonly editable: readonly (infer Field extends string)[];
|
|
262
|
+
} ? Field : AdminWritable<EntityRowIn<O>>;
|
|
248
263
|
type AdminDefOf<O, Name extends AdminMethodName> = {
|
|
249
264
|
adminList: AdminListDef<EntityRowIn<O>, FieldsIn<O, "filter">, FieldsIn<O, "sort">>;
|
|
250
265
|
adminGet: AdminGetDef<EntityRowIn<O>>;
|
|
251
|
-
adminCreate: AdminCreateDef<EntityRowIn<O>>;
|
|
252
|
-
adminUpdate: AdminUpdateDef<EntityRowIn<O>>;
|
|
266
|
+
adminCreate: AdminCreateDef<EntityRowIn<O>, EditableIn<O>>;
|
|
267
|
+
adminUpdate: AdminUpdateDef<EntityRowIn<O>, EditableIn<O>>;
|
|
253
268
|
adminDelete: AdminDeleteDef;
|
|
254
269
|
adminMeta: AdminMetaDef;
|
|
255
270
|
adminSubscribers: AdminSubscribersDef;
|
|
@@ -265,7 +280,7 @@ type AdminMethods<O> = {
|
|
|
265
280
|
declare function contract<const O extends AdminContractOptions>(options: O & NoInfer<AdminChecks<O>>): AdminMethods<O>;
|
|
266
281
|
/**
|
|
267
282
|
* The admin kit's contract half: `admin.contract({ entity, filter?, sort?,
|
|
268
|
-
* expose?, describe? })` makes the admin methods, which the server half
|
|
283
|
+
* editable?, expose?, describe? })` makes the admin methods, which the server half
|
|
269
284
|
* (`admin.handlers` on `./server`) implements, each open to a service-wide
|
|
270
285
|
* `Admin` grant unless the service says otherwise.
|
|
271
286
|
*/
|
|
@@ -136,7 +136,7 @@ interface AdminServiceMeta {
|
|
|
136
136
|
/**
|
|
137
137
|
* Fields no admin call writes, whatever the service configures: the row's key
|
|
138
138
|
* and its timestamps, which the database sets (4.1's non-editable fields,
|
|
139
|
-
* `
|
|
139
|
+
* 4.1 `src/server/utils/zodToAdminFields.ts:7`).
|
|
140
140
|
*/
|
|
141
141
|
declare const ADMIN_NEVER_WRITABLE: readonly string[];
|
|
142
142
|
|
|
@@ -184,18 +184,24 @@ interface AdminPage<Item> {
|
|
|
184
184
|
}
|
|
185
185
|
/** The fields no admin write sets: the row's key and its timestamps. */
|
|
186
186
|
type AdminNeverWritable = "id" | "createdAt" | "updatedAt" | "created_at" | "updated_at";
|
|
187
|
-
/** The
|
|
188
|
-
type
|
|
189
|
-
|
|
187
|
+
/** The fields an admin write sets without `editable`: any of the entity's fields but `id` and the timestamps. */
|
|
188
|
+
type AdminWritable<Row> = Exclude<keyof Row, AdminNeverWritable>;
|
|
189
|
+
/**
|
|
190
|
+
* The field values an admin write may set: those of `Field`, the fields
|
|
191
|
+
* `admin.contract({ editable })` names, else any of the entity's fields but
|
|
192
|
+
* `id` and the timestamps.
|
|
193
|
+
*/
|
|
194
|
+
type AdminData<Row, Field extends PropertyKey = AdminWritable<Row>> = {
|
|
195
|
+
readonly [Name in Field & keyof Row]?: Row[Name];
|
|
190
196
|
};
|
|
191
197
|
/** `adminCreate`: the new row's field values. */
|
|
192
|
-
interface AdminCreateInput<Row
|
|
193
|
-
readonly data: AdminData<Row>;
|
|
198
|
+
interface AdminCreateInput<Row, Field extends PropertyKey = AdminWritable<Row>> {
|
|
199
|
+
readonly data: AdminData<Row, Field>;
|
|
194
200
|
}
|
|
195
201
|
/** `adminUpdate`: the row, and the field values to change. */
|
|
196
|
-
interface AdminUpdateInput<Row
|
|
202
|
+
interface AdminUpdateInput<Row, Field extends PropertyKey = AdminWritable<Row>> {
|
|
197
203
|
readonly id: string;
|
|
198
|
-
readonly data: AdminData<Row>;
|
|
204
|
+
readonly data: AdminData<Row, Field>;
|
|
199
205
|
}
|
|
200
206
|
/** `adminCreate`'s input as its handler receives it: `data` without `undefined` values. */
|
|
201
207
|
interface AdminCreateQuery {
|
|
@@ -226,4 +232,4 @@ interface AdminSubscribers {
|
|
|
226
232
|
readonly complete: boolean;
|
|
227
233
|
}
|
|
228
234
|
|
|
229
|
-
export { ADMIN_FIELD_TYPES as A, type AdminUpdateInput as B, type AdminUpdateQuery as C, type
|
|
235
|
+
export { ADMIN_FIELD_TYPES as A, type AdminUpdateInput as B, type AdminUpdateQuery as C, type AdminWritable as D, type SubscriberLevel as E, type FilterValue as F, LIST_DEFAULT_LIMIT as L, SEARCH_DEFAULT_LIMIT as S, LIST_MAX_LIMIT as a, type ListPage as b, type ListQuery as c, type ListSort as d, SEARCH_DEFAULT_MIN_LENGTH as e, SEARCH_MAX_LIMIT as f, SEARCH_MAX_QUERY_LENGTH as g, type SearchInput as h, type SearchPage as i, type SearchQuery as j, ADMIN_NEVER_WRITABLE as k, type AdminFieldConfig as l, type AdminFieldType as m, type AdminServiceMeta as n, ADMIN_DEFAULT_PAGE_SIZE as o, ADMIN_MAX_PAGE as p, ADMIN_MAX_PAGE_SIZE as q, type AdminCreateInput as r, type AdminCreateQuery as s, type AdminData as t, type AdminListInput as u, type AdminListQuery as v, type AdminMetaInput as w, type AdminNeverWritable as x, type AdminPage as y, type AdminSubscribers as z };
|
|
@@ -4,7 +4,7 @@ import { A as AccessLevel, J as AnyContract, y as CollectionWhere, O as OrderBy,
|
|
|
4
4
|
import { P as Principal, Q as QuickdrawTypes, M as MaybePromise, c as PrincipalOf, a as McpContext, T as Transport, C as ContextExtensionOf, b as McpContextOf, D as DbOf } from './types-Bwg3kIEc.js';
|
|
5
5
|
|
|
6
6
|
/** What a development warning is about. */
|
|
7
|
-
type DevWarningKind = "n-plus-one" | "unbounded-read" | "oversized-response" | "nested-write" | "ambient-write" | "batch-read" | "batch-create-many" | "repeated-call" | "tiered-field-in-output";
|
|
7
|
+
type DevWarningKind = "n-plus-one" | "unbounded-read" | "oversized-response" | "nested-write" | "ambient-write" | "batch-read" | "batch-create-many" | "repeated-call" | "tiered-field-in-output" | "resolver-without-reads";
|
|
8
8
|
/** One development warning. */
|
|
9
9
|
interface DevWarning {
|
|
10
10
|
readonly kind: DevWarningKind;
|
|
@@ -659,7 +659,7 @@ interface ServerRooms {
|
|
|
659
659
|
/**
|
|
660
660
|
* `ctx.rooms` (RFC 0003 sections 3, 12.5 and 15): app-defined rooms the
|
|
661
661
|
* calling socket joins and leaves, and typed room events. It replaces 4.1's
|
|
662
|
-
* `emitToRoom` and `emitToUserRoom` (`
|
|
662
|
+
* `emitToRoom` and `emitToUserRoom` (4.1 `src/server/BaseService.ts:378-441`).
|
|
663
663
|
* Everything that needs no calling socket is also on `qd.rooms`
|
|
664
664
|
* ({@link ServerRooms}).
|
|
665
665
|
*/
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
INTERNAL_MESSAGE,
|
|
8
8
|
QuickdrawError,
|
|
9
9
|
isErrorCode
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-4YO5H5ON.js";
|
|
11
11
|
|
|
12
12
|
// src/server/caller.ts
|
|
13
13
|
var CALLER_GRANTS = /* @__PURE__ */ new WeakMap();
|
|
@@ -699,4 +699,4 @@ export {
|
|
|
699
699
|
createContext,
|
|
700
700
|
withSignal
|
|
701
701
|
};
|
|
702
|
-
//# sourceMappingURL=chunk-
|
|
702
|
+
//# sourceMappingURL=chunk-2XJFNVHW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/caller.ts","../src/server/pipeline/errors.ts","../src/server/pipeline/schemaOutput.ts","../src/server/pipeline/validation.ts","../src/server/context.ts"],"sourcesContent":["// The in-process caller (RFC 0003 section 10): `caller.taskService.rename(input)`\n// runs the same pipeline as a socket call, with transport `\"internal\"`. Its\n// types come from the contracts: a method takes what a client would pass\n// (`InputOf`) and resolves with what a client would receive (`OutputOf`).\n// A failed call rejects with its `QuickdrawError`; an `INTERNAL` one keeps\n// the original error as `cause`.\n//\n// A caller through a server's dispatcher (`qd.caller`, `server.dispatcher.caller`)\n// gives a principal that carries no `serviceAccess` the grants the server's\n// `auth.loadServiceAccess` loads, as a socket's handshake and an HTTP call\n// do (finding F5.1 of the quickdraw-chat migration: an app's REST route ran\n// its in-process call with no grants at all): once per caller, at its first\n// call, and again after the server applied new grants to a user\n// (`access.refresh`, a written grant, another node's broadcast), as a\n// socket's are refreshed. A principal that carries grants, even `{}`, keeps\n// exactly those.\n\nimport type { AnyContract } from \"../contract/defineContract\";\nimport type { ContractMap, InputOf, MethodName, OutputOf } from \"../contract/infer\";\nimport { INTERNAL_MESSAGE, QuickdrawError } from \"../protocol/errors\";\nimport type { Dispatch } from \"./pipeline/pipeline\";\nimport type { DispatchRequest } from \"./pipeline/request\";\nimport type { ServerAuth } from \"./transports/auth\";\nimport type { Principal, QuickdrawTypes } from \"./types\";\n\n/** Options of one in-process call. */\nexport interface CallOptions {\n /** Cancels the call (queries only), like a client's `qd:cancel`. */\n readonly signal?: AbortSignal;\n}\n\n/** One method of the in-process caller. The input may be left out when the method accepts `undefined`. */\nexport type MethodCaller<C extends AnyContract, M extends MethodName<C>> = (\n ...args: undefined extends InputOf<C, M>\n ? [input?: InputOf<C, M>, options?: CallOptions]\n : [input: InputOf<C, M>, options?: CallOptions]\n) => Promise<OutputOf<C, M>>;\n\n/** The in-process caller of one service: one function per method. */\nexport type ServiceCaller<C extends AnyContract> = {\n readonly [M in MethodName<C>]: MethodCaller<C, M>;\n};\n\n/** The in-process caller of a set of contracts, by service name: `caller.taskService.rename(input)`. */\nexport type Caller<C extends AnyContract> = {\n readonly [Name in C[\"name\"]]: ServiceCaller<Extract<C, { readonly name: Name }>>;\n};\n\n/**\n * The type of `qd.caller(principal)`: typed from the app's `contracts` when\n * `QuickdrawTypes` declares them, and untyped (any service, method and\n * input) otherwise.\n */\nexport type CallerFor<T extends QuickdrawTypes> = T extends {\n readonly contracts: infer Contracts extends ContractMap;\n}\n ? Caller<Contracts[keyof Contracts]>\n : Caller<AnyContract>;\n\n/** Where the in-process callers of a server's dispatcher get the grants of a principal that carries none. */\nexport interface CallerGrants {\n /** The server's `auth.loadServiceAccess`. */\n readonly load: NonNullable<ServerAuth[\"loadServiceAccess\"]>;\n /**\n * Rises each time the server applies new grants to a user: a caller that\n * loaded its principal's grants before loads them again at its next call.\n */\n readonly version: () => number;\n}\n\nconst CALLER_GRANTS = new WeakMap<object, CallerGrants>();\n\n/**\n * Makes the in-process callers of `dispatcher` (its `caller`, and `qd.caller`\n * while it is the current one) load grants through `grants`: `createServer`\n * registers its `auth.loadServiceAccess`.\n */\nexport function setCallerGrants(dispatcher: object, grants: CallerGrants): void {\n CALLER_GRANTS.set(dispatcher, grants);\n}\n\n/** Where the callers of `dispatcher` load grants from, or `undefined` when they load none. */\nexport function callerGrantsOf(dispatcher: object | undefined): CallerGrants | undefined {\n return dispatcher === undefined ? undefined : CALLER_GRANTS.get(dispatcher);\n}\n\n/** How the calls of a {@link createCaller} run. */\nexport interface CallerSettings {\n /** Cancels every call too: `ctx.services` passes the calling method's `ctx.signal`. */\n readonly signal?: AbortSignal;\n /** Where to load a principal's grants from, asked at each call; `undefined` loads none. */\n readonly grants?: () => CallerGrants | undefined;\n}\n\ntype MethodFunction = (input?: unknown, options?: CallOptions) => Promise<unknown>;\n\nasync function invoke(resolve: () => Dispatch, request: DispatchRequest): Promise<unknown> {\n const result = await resolve()(request);\n if (!result.ok) {\n throw result.error;\n }\n return result.notModified === true ? undefined : result.data;\n}\n\n/**\n * A read-only object whose members are made on first access and kept. It is\n * never mistaken for a promise: `then` reads as `undefined`.\n */\nexport function lazyMembers<Member>(make: (name: string) => Member): object {\n const made = new Map<string, Member>();\n return new Proxy(Object.freeze({}), {\n get(_target, name) {\n if (typeof name !== \"string\" || name === \"then\") {\n return undefined;\n }\n let member = made.get(name);\n if (member === undefined) {\n member = make(name);\n made.set(name, member);\n }\n return member;\n },\n });\n}\n\n/** `signal`, and also `outer` when there is one: aborted when either is. */\nfunction bothSignals(outer: AbortSignal | undefined, signal: AbortSignal | undefined) {\n if (outer === undefined || signal === undefined) {\n return outer ?? signal;\n }\n return AbortSignal.any([outer, signal]);\n}\n\n/** True when `principal` carries grants of its own (`{}` included): they are kept as they are. */\nfunction carriesGrants(principal: Principal): boolean {\n return principal.serviceAccess !== undefined && principal.serviceAccess !== null;\n}\n\n/** `principal` with the grants `grants` loads (`{}` for none). A failed load is `INTERNAL`, keeping the error as `cause`. */\nasync function withLoadedGrants(principal: Principal, grants: CallerGrants): Promise<Principal> {\n let serviceAccess: Awaited<ReturnType<CallerGrants[\"load\"]>>;\n try {\n serviceAccess = await grants.load(principal.userId);\n } catch (error) {\n const failure = new QuickdrawError(\"INTERNAL\", INTERNAL_MESSAGE);\n failure.cause = error;\n throw failure;\n }\n return { ...principal, serviceAccess: serviceAccess ?? {} };\n}\n\n/** What each call of a caller runs as: the principal, or a promise of it while its grants load. */\ntype PrincipalOfCall = () => Principal | null | Promise<Principal>;\n\n/**\n * The principal each call of a caller runs as: `principal` itself when it is\n * `null`, carries grants, or `grants` gives no loader; else `principal` with\n * the grants loaded at the first call, kept until the server applied new\n * grants to a user (its version rose) or the loader changed. A load that\n * failed is not kept: the next call loads again.\n */\nfunction principalOfCalls(\n principal: Principal | null,\n grants: CallerSettings[\"grants\"],\n): PrincipalOfCall {\n if (principal === null || carriesGrants(principal) || grants === undefined) {\n return () => principal;\n }\n interface Held {\n readonly from: CallerGrants;\n readonly version: number;\n readonly loading: Promise<Principal>;\n loaded?: Principal;\n }\n let held: Held | undefined;\n return () => {\n const from = grants();\n if (from === undefined) {\n return principal;\n }\n const version = from.version();\n if (held?.from === from && held.version === version) {\n return held.loaded ?? held.loading;\n }\n const entry: Held = { from, version, loading: withLoadedGrants(principal, from) };\n held = entry;\n entry.loading.then(\n (loaded) => {\n entry.loaded = loaded;\n },\n () => {\n if (held === entry) {\n held = undefined;\n }\n },\n );\n return entry.loading;\n };\n}\n\n/**\n * Creates an in-process caller acting as `principal` (`null` for an\n * anonymous caller). `resolve` returns the dispatch function to call through;\n * it is asked on every call, so a caller made before its dispatcher exists\n * works once one does. Every call is also cancelled with `settings.signal`,\n * when given (`ctx.services` passes the calling method's `ctx.signal`). With\n * `settings.grants`, a principal that carries no grants calls with the ones\n * it loads (see the top of this file).\n */\nexport function createCaller(\n resolve: () => Dispatch,\n principal: Principal | null,\n settings: CallerSettings = {},\n): object {\n const principalOfCall = principalOfCalls(principal, settings.grants);\n return lazyMembers((service) =>\n lazyMembers<MethodFunction>((method) => async (input, options) => {\n const runAs = principalOfCall();\n return await invoke(resolve, {\n service,\n method,\n input,\n // Awaited only while grants load: a known principal is dispatched at once, as before.\n principal: runAs instanceof Promise ? await runAs : runAs,\n transport: \"internal\",\n signal: bothSignals(settings.signal, options?.signal),\n });\n }),\n );\n}\n","// How the pipeline turns whatever a stage or handler threw into the error the\n// caller receives (RFC 0003 section 3). A `QuickdrawError` with one of the\n// error codes passes through. Prisma's two known request errors that callers\n// can act on become `CONFLICT` and `NOT_FOUND`. Everything else becomes\n// `INTERNAL` with the generic message, keeping the original as `cause` for\n// the log and for in-process callers; `toWire` never sends it. That includes\n// a `QuickdrawError` whose code is not one of the error codes, which a cast or\n// a 4.x port (`new QuickdrawError(404, ...)`) can build: no transport has a\n// reply or an HTTP status for it.\n\nimport { INTERNAL_MESSAGE, isErrorCode, QuickdrawError } from \"../../protocol/errors\";\n\n/** The error a cancelled call settles with. */\nexport function cancelledError(): QuickdrawError {\n return new QuickdrawError(\"CANCELLED\", \"The call was cancelled\");\n}\n\n/** The error a call settles with when its handler runs past the time limit. */\nexport function timeoutError(timeoutMs: number): QuickdrawError {\n return new QuickdrawError(\"TIMEOUT\", `The call ran past its time limit of ${timeoutMs} ms`);\n}\n\n/** Throws `CANCELLED` when `signal` has aborted. */\nexport function throwIfCancelled(signal: AbortSignal | undefined): void {\n if (signal?.aborted === true) {\n throw cancelledError();\n }\n}\n\n/**\n * The error a call settles with once its signal aborted: the `TIMEOUT` error\n * its time limit aborted it with, or else `CANCELLED`.\n */\nexport function abortError(signal: AbortSignal): QuickdrawError {\n const reason: unknown = signal.reason;\n return reason instanceof QuickdrawError && reason.code === \"TIMEOUT\" ? reason : cancelledError();\n}\n\nfunction prismaError(error: unknown): QuickdrawError | undefined {\n if (!(error instanceof Error) || error.name !== \"PrismaClientKnownRequestError\") {\n return undefined;\n }\n const { code } = error as Error & { readonly code?: unknown };\n if (code === \"P2002\") {\n return new QuickdrawError(\"CONFLICT\", \"A unique constraint failed\");\n }\n if (code === \"P2025\") {\n return new QuickdrawError(\"NOT_FOUND\", \"Record not found\");\n }\n return undefined;\n}\n\n/**\n * The `QuickdrawError` a caller receives for `error`. Anything but a\n * `QuickdrawError` with a known code becomes another error that keeps the\n * original as `cause`, so it can be logged in full.\n */\nexport function toQuickdrawError(error: unknown): QuickdrawError {\n if (error instanceof QuickdrawError && isErrorCode(error.code)) {\n return error;\n }\n const mapped = prismaError(error) ?? new QuickdrawError(\"INTERNAL\", INTERNAL_MESSAGE);\n mapped.cause = error;\n return mapped;\n}\n","// Schema outputs (RFC 0003 section 9, step 8): a method whose output is a\n// schema of its own, not `\"entity\"` and not a projection, sends its result\n// reduced to what that schema's JSON Schema declares, on every transport and\n// whatever `outputValidation` is. A handler may return a whole row; only the\n// keys the schema declares leave the server. rc.5 and before sent what the\n// handler returned, so `{ id, name }` answered with `db.user.update(...)`\n// sent `email` too (the final review of the release candidates, item B).\n//\n// The reduction is compiled once per method, when its service is defined,\n// from the schema's Standard JSON Schema (draft-07, a value JSON Schema\n// cannot write read as any value): a call walks the compiled shapes and\n// never reads the schema. What a value keeps, by what the schema says there:\n//\n// | JSON Schema | A value there keeps |\n// |-------------------------------------------|------------------------------------------------------|\n// | an object with `properties` | the keys `properties` declares, each reduced by its |\n// | | own schema; another key only where |\n// | | `patternProperties` matches it or |\n// | | `additionalProperties` allows it (`true`, `{}`, or a |\n// | | schema that reduces its value) |\n// | an object declaring no key (a record, | every key, each value reduced by |\n// | `{ type: \"object\" }`) | `additionalProperties` when it is a schema |\n// | an array | its items, each reduced by `items` (a tuple's by |\n// | | position, the rest by `additionalItems`) |\n// | `anyOf`, `oneOf`, `allOf` | what any of its schemas keeps |\n// | `{}` (any value), `true`, a `$ref` it | everything, as it is |\n// | cannot follow | |\n// | a scalar (`string`, `const`, `enum`, ...) | a scalar as it is; a plain object there keeps no key |\n//\n// Only plain objects and arrays are reduced: a `Date`, a `Decimal` or a\n// class instance goes as it is. Nothing is copied unless a key or an item is\n// dropped, so a handler that returns exactly its schema's keys costs one\n// pass over them. An output without JSON Schema (a Zod 3 schema) cannot be\n// reduced and is sent as returned; in development its reply is checked for\n// keys the contract tiers instead (`emit/tieredOutputs.ts`).\n\nimport { hasJsonSchema, type StandardSchemaV1 } from \"../../contract/standardSchema\";\nimport type { SchemaOutput } from \"../service\";\n\ntype JsonNode = Readonly<Record<string, unknown>>;\n\n/** How the values at one place of an output are reduced. */\ninterface Shape {\n /** Any value: kept as it is. */\n readonly any: boolean;\n /** How a plain object there is reduced; without one, it keeps no key. */\n object: ObjectShape | undefined;\n /** How an array there is reduced; without one, each item is reduced by this shape. */\n array: ArrayShape | undefined;\n}\n\ninterface ObjectShape {\n /** The declared keys' shapes, in an object without a prototype: a lookup per key is a property read. */\n readonly properties: Readonly<Record<string, Shape | undefined>>;\n readonly patterns: readonly { readonly regex: RegExp; readonly shape: Shape }[];\n /** How the value of a key `properties` and `patterns` do not declare is reduced; `undefined` drops the key. */\n readonly additional: Shape | undefined;\n}\n\ninterface ArrayShape {\n readonly prefix: readonly Shape[];\n /** How the items past `prefix` are reduced; `undefined` drops them. */\n readonly rest: Shape | undefined;\n}\n\n/** Any value, kept as it is. */\nconst ANY: Shape = Object.freeze({ any: true, object: undefined, array: undefined });\n\n/** What one JSON Schema node declares on its own, before its `anyOf`, `oneOf`, `allOf` and `$ref`. */\ninterface Node {\n readonly id: number;\n any: boolean;\n object:\n | {\n properties: Map<string, Node>;\n patterns: { regex: RegExp; node: Node }[];\n additional: Node | undefined;\n }\n | undefined;\n array: { prefix: Node[]; rest: Node | undefined } | undefined;\n /** The schemas it is one of, or all of: its branches and the node its `$ref` names. */\n readonly members: Node[];\n}\n\nfunction isRecord(value: unknown): value is JsonNode {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** True for an object literal, or `Object.create(null)`, of any realm: what a reduction may copy. */\nfunction isPlainObject(value: object): value is Readonly<Record<string, unknown>> {\n const prototype = Object.getPrototypeOf(value) as object | null;\n return (\n prototype === Object.prototype ||\n prototype === null ||\n Object.getPrototypeOf(prototype) === null\n );\n}\n\n/** The node a `$ref` names in the document: `#`, or a JSON Pointer into it; `undefined` when it names none. */\nfunction follow(ref: string, root: JsonNode): unknown {\n if (ref === \"#\") {\n return root;\n }\n if (!ref.startsWith(\"#/\")) {\n return undefined;\n }\n let node: unknown = root;\n for (const raw of ref.slice(2).split(\"/\")) {\n let part: string;\n try {\n part = decodeURIComponent(raw).replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n } catch {\n return undefined;\n }\n node = isRecord(node) && Object.hasOwn(node, part) ? node[part] : undefined;\n }\n return node;\n}\n\nconst BRANCHES = [\"anyOf\", \"oneOf\", \"allOf\"] as const;\n\nfunction hasAny(node: JsonNode, keywords: readonly string[]): boolean {\n return keywords.some((keyword) => node[keyword] !== undefined);\n}\n\nfunction typesOf(node: JsonNode): readonly unknown[] | undefined {\n const { type } = node;\n if (typeof type === \"string\") {\n return [type];\n }\n return Array.isArray(type) ? type : undefined;\n}\n\nfunction patternOf(source: string): RegExp | undefined {\n try {\n return new RegExp(source, \"u\");\n } catch {\n try {\n return new RegExp(source);\n } catch {\n return undefined;\n }\n }\n}\n\n/** Every node `nodes` stand for: themselves and, through their members, the schemas they combine. */\nfunction expand(nodes: readonly Node[]): Node[] {\n const seen = new Set<Node>();\n const pending = [...nodes];\n for (let node = pending.pop(); node !== undefined; node = pending.pop()) {\n if (!seen.has(node)) {\n seen.add(node);\n pending.push(...node.members);\n }\n }\n return [...seen];\n}\n\n/**\n * Compiles one JSON Schema document: reads it into nodes (each JSON node\n * once, `$ref` cycles included), then builds the shapes calls walk, one per\n * set of nodes a value may meet, merged once.\n */\nclass Compiler {\n private next = 0;\n private readonly nodes = new Map<unknown, Node>();\n private readonly shapes = new Map<string, Shape>();\n\n constructor(private readonly root: JsonNode) {}\n\n private make(any: boolean): Node {\n this.next += 1;\n return { id: this.next, any, object: undefined, array: undefined, members: [] };\n }\n\n /** The node a JSON Schema value stands for. `true` and absent are any value. */\n read(value: unknown): Node {\n if (value === undefined || value === true) {\n return this.make(true);\n }\n if (!isRecord(value)) {\n // `false` (no value) and anything malformed: a scalar, which keeps no key of an object.\n return this.make(false);\n }\n const known = this.nodes.get(value);\n if (known !== undefined) {\n return known;\n }\n const node = this.make(false);\n this.nodes.set(value, node);\n this.readMembers(node, value);\n this.readParts(node, value);\n return node;\n }\n\n /** The node's `$ref` target and its `anyOf`, `oneOf` and `allOf` branches. */\n private readMembers(node: Node, json: JsonNode): void {\n const { $ref } = json;\n if (typeof $ref === \"string\") {\n const target = follow($ref, this.root);\n node.members.push(target === undefined ? this.make(true) : this.read(target));\n }\n for (const keyword of BRANCHES) {\n const members = json[keyword];\n if (!Array.isArray(members)) {\n continue;\n }\n for (const member of members) {\n const read = this.read(member);\n // A part of an `allOf` that allows any value adds nothing to the others.\n if (!(keyword === \"allOf\" && read.any && members.length > 1)) {\n node.members.push(read);\n }\n }\n }\n }\n\n /** What the node declares itself: an object, an array, a scalar, or any value. */\n private readParts(node: Node, json: JsonNode): void {\n const types = typesOf(json);\n const combined = node.members.length > 0;\n const objectKeywords = hasAny(json, [\n \"properties\",\n \"patternProperties\",\n \"additionalProperties\",\n ]);\n const arrayKeywords = hasAny(json, [\"items\", \"prefixItems\", \"additionalItems\"]);\n if (objectKeywords) {\n node.object = this.readObject(json);\n } else if (!combined && types?.includes(\"object\") === true) {\n // An object that declares no key, as a record does: every key.\n node.object = { properties: new Map(), patterns: [], additional: this.make(true) };\n }\n if (arrayKeywords) {\n node.array = this.readArray(json);\n } else if (!combined && types?.includes(\"array\") === true) {\n node.array = { prefix: [], rest: this.make(true) };\n }\n const scalar = types !== undefined || hasAny(json, [\"const\", \"enum\"]);\n node.any = !combined && !objectKeywords && !arrayKeywords && !scalar;\n }\n\n private readObject(json: JsonNode): NonNullable<Node[\"object\"]> {\n const properties = new Map<string, Node>();\n if (isRecord(json.properties)) {\n for (const [key, schema] of Object.entries(json.properties)) {\n properties.set(key, this.read(schema));\n }\n }\n const patterns: { regex: RegExp; node: Node }[] = [];\n let open = false;\n if (isRecord(json.patternProperties)) {\n for (const [source, schema] of Object.entries(json.patternProperties)) {\n const regex = patternOf(source);\n if (regex === undefined) {\n open = true;\n } else {\n patterns.push({ regex, node: this.read(schema) });\n }\n }\n }\n const { additionalProperties } = json;\n let additional: Node | undefined;\n if (open) {\n additional = this.make(true);\n } else if (additionalProperties === undefined) {\n // Properties declared and nothing said of the others: the declared keys only.\n additional =\n json.properties === undefined && json.patternProperties === undefined\n ? this.make(true)\n : undefined;\n } else {\n additional = additionalProperties === false ? undefined : this.read(additionalProperties);\n }\n return { properties, patterns, additional };\n }\n\n private readArray(json: JsonNode): NonNullable<Node[\"array\"]> {\n const { items, prefixItems, additionalItems } = json;\n if (Array.isArray(items)) {\n // draft-07's tuple: `items` by position, `additionalItems` past them.\n return {\n prefix: items.map((item: unknown) => this.read(item)),\n rest: additionalItems === false ? undefined : this.read(additionalItems),\n };\n }\n const prefix = Array.isArray(prefixItems)\n ? prefixItems.map((item: unknown) => this.read(item))\n : [];\n return { prefix, rest: items === false ? undefined : this.read(items) };\n }\n\n /** The shape of a value any of `nodes` describes. */\n shapeOf(nodes: readonly Node[]): Shape {\n const all = expand(nodes);\n if (all.some((node) => node.any)) {\n return ANY;\n }\n const key = all\n .map((node) => node.id)\n .sort((a, b) => a - b)\n .join(\",\");\n const known = this.shapes.get(key);\n if (known !== undefined) {\n return known;\n }\n // Registered before its parts are built, so a recursive schema meets itself.\n const shape: Shape = { any: false, object: undefined, array: undefined };\n this.shapes.set(key, shape);\n const objects = all.flatMap((node) => (node.object === undefined ? [] : [node.object]));\n const arrays = all.flatMap((node) => (node.array === undefined ? [] : [node.array]));\n shape.object = objects.length === 0 ? undefined : this.objectShapeOf(objects);\n shape.array = arrays.length === 0 ? undefined : this.arrayShapeOf(arrays);\n return shape;\n }\n\n private objectShapeOf(objects: readonly NonNullable<Node[\"object\"]>[]): ObjectShape {\n const keys = new Set(objects.flatMap((object) => [...object.properties.keys()]));\n const properties = Object.create(null) as Record<string, Shape>;\n for (const key of keys) {\n const nodes = objects.flatMap((object) => {\n const declared =\n object.properties.get(key) ??\n object.patterns.find(({ regex }) => regex.test(key))?.node ??\n object.additional;\n return declared === undefined ? [] : [declared];\n });\n properties[key] = this.shapeOf(nodes);\n }\n const patterns = objects.flatMap((object) =>\n object.patterns.map(({ regex, node }) => ({ regex, shape: this.shapeOf([node]) })),\n );\n const additional = objects.flatMap((object) =>\n object.additional === undefined ? [] : [object.additional],\n );\n return {\n properties,\n patterns,\n additional: additional.length === 0 ? undefined : this.shapeOf(additional),\n };\n }\n\n private arrayShapeOf(arrays: readonly NonNullable<Node[\"array\"]>[]): ArrayShape {\n const length = Math.max(...arrays.map((array) => array.prefix.length));\n const at = (index: number): Node[] =>\n arrays.flatMap((array) => {\n const node = index < array.prefix.length ? array.prefix[index] : array.rest;\n return node === undefined ? [] : [node];\n });\n const prefix = Array.from({ length }, (_, index) => this.shapeOf(at(index)));\n const rest = arrays.flatMap((array) => (array.rest === undefined ? [] : [array.rest]));\n return { prefix, rest: rest.length === 0 ? undefined : this.shapeOf(rest) };\n }\n}\n\n/** Marks a key or an item a reduction drops. */\nconst DROPPED: unique symbol = Symbol(\"dropped\");\n\n/** Sets `key` on a copy, `__proto__` too, as an own key. */\nfunction assign(copy: Record<string, unknown>, key: string, value: unknown): void {\n if (key === \"__proto__\") {\n Object.defineProperty(copy, key, {\n value,\n enumerable: true,\n writable: true,\n configurable: true,\n });\n } else {\n copy[key] = value;\n }\n}\n\nfunction shapeOfKey(object: ObjectShape, key: string): Shape | undefined {\n const declared = object.properties[key];\n if (declared !== undefined) {\n return declared;\n }\n for (const { regex, shape } of object.patterns) {\n if (regex.test(key)) {\n return shape;\n }\n }\n return object.additional;\n}\n\n/** `item` as `shape` keeps it, or `DROPPED`; a scalar is kept without a call. */\nfunction keep(shape: Shape | undefined, item: unknown): unknown {\n if (shape === undefined) {\n return DROPPED;\n }\n return shape.any || typeof item !== \"object\" || item === null ? item : reduce(shape, item);\n}\n\nfunction reduceObject(\n object: ObjectShape | undefined,\n value: Readonly<Record<string, unknown>>,\n): Readonly<Record<string, unknown>> {\n const keys = Object.keys(value);\n let copy: Record<string, unknown> | undefined;\n for (let index = 0; index < keys.length; index += 1) {\n const key = keys[index] as string;\n const item = value[key];\n const kept = keep(object === undefined ? undefined : shapeOfKey(object, key), item);\n if (copy === undefined) {\n if (kept === item) {\n continue;\n }\n copy = {};\n for (let earlier = 0; earlier < index; earlier += 1) {\n const name = keys[earlier] as string;\n assign(copy, name, value[name]);\n }\n }\n if (kept !== DROPPED) {\n assign(copy, key, kept);\n }\n }\n return copy ?? value;\n}\n\nfunction reduceArray(shape: Shape, value: readonly unknown[]): readonly unknown[] {\n const { array } = shape;\n let copy: unknown[] | undefined;\n for (let index = 0; index < value.length; index += 1) {\n const item: unknown = value[index];\n const kept = keep(\n array === undefined ? shape : index < array.prefix.length ? array.prefix[index] : array.rest,\n item,\n );\n if (copy === undefined) {\n if (kept === item) {\n continue;\n }\n copy = value.slice(0, index);\n }\n if (kept !== DROPPED) {\n copy.push(kept);\n }\n }\n return copy ?? value;\n}\n\n/** An object `value` as `shape` keeps it. */\nfunction reduce(shape: Shape, value: object): unknown {\n if (Array.isArray(value)) {\n return reduceArray(shape, value);\n }\n return isPlainObject(value) ? reduceObject(shape.object, value) : value;\n}\n\n/** Where a shape declares each key it names, at any depth: the shortest path found first. */\nfunction keyPaths(root: Shape): ReadonlyMap<string, string> {\n const paths = new Map<string, string>();\n const seen = new Set<Shape>();\n const queue: { readonly shape: Shape; readonly path: string }[] = [{ shape: root, path: \"\" }];\n for (let index = 0; index < queue.length; index += 1) {\n const { shape, path } = queue[index] as { readonly shape: Shape; readonly path: string };\n if (seen.has(shape)) {\n continue;\n }\n seen.add(shape);\n if (shape.object !== undefined) {\n for (const [key, child] of Object.entries(shape.object.properties)) {\n if (child === undefined) {\n continue;\n }\n const at = path === \"\" ? key : `${path}.${key}`;\n if (!paths.has(key)) {\n paths.set(key, at);\n }\n queue.push({ shape: child, path: at });\n }\n for (const { shape: child } of shape.object.patterns) {\n queue.push({ shape: child, path: `${path}{}` });\n }\n if (shape.object.additional !== undefined) {\n queue.push({ shape: shape.object.additional, path: `${path}{}` });\n }\n }\n if (shape.array !== undefined) {\n for (const child of shape.array.prefix) {\n queue.push({ shape: child, path: `${path}[]` });\n }\n if (shape.array.rest !== undefined) {\n queue.push({ shape: shape.array.rest, path: `${path}[]` });\n }\n }\n }\n return paths;\n}\n\n/** Writes values JSON Schema has no form for as `{}` (any value), keeping the keys beside them (Zod 4). */\nconst UNREPRESENTABLE_AS_ANY = Object.freeze({ unrepresentable: \"any\" });\n\n/**\n * Compiles a method's output schema (see the top of this file), or\n * `undefined` when it has no Standard JSON Schema or cannot write one: such\n * an output is sent as the handler returns it.\n */\nexport function compileSchemaOutput(schema: StandardSchemaV1): SchemaOutput | undefined {\n if (!hasJsonSchema(schema)) {\n return undefined;\n }\n let json: unknown;\n try {\n json = schema[\"~standard\"].jsonSchema.output({\n target: \"draft-07\",\n libraryOptions: UNREPRESENTABLE_AS_ANY,\n });\n } catch {\n return undefined;\n }\n if (!isRecord(json)) {\n return undefined;\n }\n const compiler = new Compiler(json);\n const root = compiler.shapeOf([compiler.read(json)]);\n let paths: ReadonlyMap<string, string> | undefined;\n return Object.freeze({\n pick: (value: unknown) => keep(root, value),\n keyPaths: () => (paths ??= keyPaths(root)),\n });\n}\n","// Input and output validation (RFC 0003 section 9, steps 3 and 8). Input\n// failures reach the caller as `VALIDATION` with `data.issues` in the wire\n// shape `{ path, message }[]`. 4.1 sent Zod's message as a code-400 string\n// (4.1 `src/server/ServiceRegistry.ts:296-305`), and only when the method\n// had a schema at all.\n\nimport type { AnyContract } from \"../../contract/defineContract\";\nimport type { MethodOutput } from \"../../contract/methods\";\nimport {\n isStandardSchema,\n validate,\n type StandardSchemaV1,\n type ValidationIssue,\n} from \"../../contract/standardSchema\";\nimport { QuickdrawError, type WireIssue } from \"../../protocol/errors\";\nimport type { SchemaOutput } from \"../service\";\nimport { compileSchemaOutput } from \"./schemaOutput\";\n\ntype PathSegment = NonNullable<ValidationIssue[\"path\"]>[number];\n\nfunction wireKey(key: PropertyKey): string | number {\n if (typeof key === \"symbol\") {\n return key.description ?? key.toString();\n }\n return key;\n}\n\nfunction wireSegment(segment: PathSegment): string | number {\n return typeof segment === \"object\" ? wireKey(segment.key) : wireKey(segment);\n}\n\n/**\n * Standard Schema issues in the wire shape of RFC 0003 section 3: each path\n * as object keys and array indexes (a `{ key }` segment becomes its key, a\n * symbol its description), and the message unchanged.\n */\nexport function toWireIssues(issues: readonly ValidationIssue[]): WireIssue[] {\n return issues.map((issue) => ({\n path: (issue.path ?? []).map(wireSegment),\n message: issue.message,\n }));\n}\n\n/** Validates a call's input. Resolves with the parsed input, or rejects with `VALIDATION`. */\nexport async function parseInput(\n schema: StandardSchemaV1,\n input: unknown,\n label: string,\n): Promise<unknown> {\n const result = await validate(schema, input);\n if (result.issues !== undefined) {\n throw new QuickdrawError(\"VALIDATION\", `Invalid input for ${label}`, {\n issues: toWireIssues(result.issues),\n });\n }\n return result.value;\n}\n\nfunction derivedSchema(validateValue: StandardSchemaV1.Props[\"validate\"]): StandardSchemaV1 {\n return Object.freeze({\n \"~standard\": Object.freeze({ version: 1, vendor: \"quickdraw\", validate: validateValue }),\n });\n}\n\nfunction nullableOf(inner: StandardSchemaV1): StandardSchemaV1 {\n return derivedSchema((value) =>\n value === null ? { value } : inner[\"~standard\"].validate(value),\n );\n}\n\nfunction listOfSchema(inner: StandardSchemaV1): StandardSchemaV1 {\n return derivedSchema(async (value) => {\n if (!Array.isArray(value)) {\n return { issues: [{ message: \"Expected an array\", path: [] }] };\n }\n const results = await Promise.all(value.map((item: unknown) => validate(inner, item)));\n const issues = results.flatMap((result, index) =>\n (result.issues ?? []).map((issue) => ({\n message: issue.message,\n path: [index, ...(issue.path ?? [])],\n })),\n );\n return issues.length > 0 ? { issues } : { value };\n });\n}\n\nfunction projectionSchema(contract: AnyContract, projection: string): StandardSchemaV1 {\n const found = projection === \"entity\" ? contract.entity : contract.projections[projection];\n if (found === undefined) {\n throw new TypeError(\n `defineService(\"${contract.name}\"): output names unknown projection \"${projection}\"`,\n );\n }\n return found;\n}\n\n/**\n * The schema a method's result is checked against: its `output` schema, or\n * the entity or projection schema it names, wrapped for `nullable(...)` and\n * `listOf(...)` (RFC 0003 section 17).\n */\nexport function outputSchemaOf(contract: AnyContract, output: MethodOutput): StandardSchemaV1 {\n if (isStandardSchema(output)) {\n return output;\n }\n if (typeof output === \"string\") {\n return projectionSchema(contract, output);\n }\n const row = projectionSchema(contract, output.projection);\n return output.kind === \"nullable\" ? nullableOf(row) : listOfSchema(row);\n}\n\n/**\n * A method output that is a schema of its own, compiled to reduce results to\n * what it declares (`schemaOutput.ts`); `undefined` for a projection output\n * or a schema without JSON Schema.\n */\nexport function schemaOutputOf(output: MethodOutput): SchemaOutput | undefined {\n return isStandardSchema(output) ? compileSchemaOutput(output) : undefined;\n}\n\n/** The problems with a handler's result, or `undefined` when it matches the method's output. */\nexport async function outputIssues(\n output: StandardSchemaV1,\n value: unknown,\n): Promise<WireIssue[] | undefined> {\n const result = await validate(output, value);\n return result.issues === undefined ? undefined : toWireIssues(result.issues);\n}\n","// The argument every handler receives, `{ input, ctx, db }` (RFC 0003\n// section 3). `ctx` replaces 4.1's `ServiceMethodContext` (`userId`,\n// `socketId`, `serviceAccess`; 4.1 `src/shared/types.ts:111-115`) and the\n// habit of overriding `defineMethod` to add fields: an app adds its own\n// fields once, through `initQuickdraw({ context })`.\n\nimport type { AnyContract } from \"../contract/defineContract\";\nimport type { Logger } from \"../contract/logger\";\nimport { QuickdrawError } from \"../protocol/errors\";\nimport type { DispatcherAccess, PolicyEngine } from \"./access/api\";\nimport { createCaller, type CallerFor } from \"./caller\";\nimport type { Dispatch } from \"./pipeline/pipeline\";\nimport type { ContextRooms, Presence } from \"./realtime/types\";\nimport type { AnyService } from \"./service\";\nimport type { StorageAdapter } from \"./storage\";\nimport type {\n ContextExtensionOf,\n DbOf,\n McpContext,\n McpContextOf,\n Principal,\n PrincipalOf,\n QuickdrawTypes,\n Transport,\n} from \"./types\";\n\n/** Options of `ctx.touch`. */\nexport interface TouchOptions {\n /** The rows were deleted rather than changed. */\n readonly removed?: boolean;\n}\n\n/**\n * `ctx.services`: in-process callers for the app's services (RFC 0003\n * sections 3 and 10), by service name: `ctx.services.projectService.get(input)`.\n * A call runs the whole pipeline (input check, access, handler, output\n * check) as the calling principal with transport `\"internal\"`, its writes\n * join the calling method's unit of work (one flush for both), and it is\n * cancelled with `ctx.signal`. Typed by the `contracts` of the app's types,\n * like `qd.caller`; untyped without them.\n */\nexport type ContextServices<T extends QuickdrawTypes = QuickdrawTypes> = CallerFor<T>;\n\nexport type { ContextRooms, Presence };\n\n/**\n * The fields of `ctx` the framework provides, whatever the app adds. `M` is\n * the type of `ctx.mcp`.\n */\nexport interface BaseContext<P = Principal, M = McpContext> {\n /**\n * Who is calling. `null` only in a `\"public\"` method called without\n * credentials; every other access form guarantees a principal.\n */\n readonly principal: P;\n /**\n * Aborts when the call is cancelled (a query whose callers all cancelled)\n * or runs past its time limit. Pass it to anything that can stop early.\n */\n readonly signal: AbortSignal;\n /** A logger bound to this call's service, method and request id. */\n readonly log: Logger;\n /** Identifies this call in logs and in its completion record. */\n readonly requestId: string;\n /** How the call arrived. */\n readonly transport: Transport;\n /**\n * The socket the call arrived on: its id, as the client socket's `id`,\n * `onRoomLeave`'s `socketId` and a channel handler's `ctx.socketId` name\n * it (a game keys a player's input by it). `undefined` for a call that\n * did not arrive over a socket: HTTP, MCP, in process, `ctx.services`. In\n * a method that shares its runs (`share`), the first caller's.\n */\n readonly socketId?: string;\n /**\n * The fields the MCP bridge's `context` option produced for this call, such\n * as the scopes of the agent's token; typed by `QuickdrawTypes[\"mcp\"]`.\n * `undefined` unless the call arrived over MCP.\n */\n readonly mcp?: M;\n /**\n * Records writes the tracked database client cannot see, raw SQL and\n * database cascades (RFC 0003 section 5.2), as if the client had made\n * them here: inside an open `db.$transaction` they join it and are dropped\n * on rollback. `target` is the model name (`\"task\"`); `removed` marks the\n * rows deleted. Does nothing when the dispatcher's `db` is not tracked.\n */\n touch(\n target: string | AnyContract,\n ids: string | readonly string[],\n options?: TouchOptions,\n ): void;\n /**\n * In-process callers for the app's services, as this call's principal:\n * `await ctx.services.projectService.get({ id })`. See {@link ContextServices}.\n */\n readonly services: ContextServices;\n /**\n * App-defined rooms the calling socket joins and leaves (`join` answers\n * `false` for a call without a socket), and typed room events: `emit` and\n * `emitToUser` (RFC 0003 section 12.5).\n */\n readonly rooms: ContextRooms;\n /** Who is online, when they were last seen, and who is in a room (RFC 0003 section 12.5). */\n readonly presence: Presence;\n}\n\n/**\n * A handler's `ctx`: the framework's fields plus the app's own from\n * `initQuickdraw({ context })`. An app field cannot replace a framework field.\n */\nexport type HandlerContext<T extends QuickdrawTypes, P = PrincipalOf<T>> = Omit<\n ContextExtensionOf<T>,\n keyof BaseContext\n> &\n Omit<BaseContext<P, McpContextOf<T>>, \"services\"> & {\n /** In-process callers for the app's services, typed by its `contracts`. */\n readonly services: ContextServices<T>;\n };\n\n/** What a handler receives: the parsed input, the call's context and the app's database client. */\nexport interface HandlerArgs<T extends QuickdrawTypes, Input, P = PrincipalOf<T>> {\n /** The input after its schema ran: defaults applied, transforms done. */\n readonly input: Input;\n readonly ctx: HandlerContext<T, P>;\n /** The database client given to the dispatcher, passed through unchanged. */\n readonly db: DbOf<T>;\n}\n\n/** Any handler's `ctx`, as the pipeline handles it. */\nexport type AnyContext = BaseContext<Principal | null>;\n\n/**\n * What `qd.run(fn)` and `dispatcher.run(fn)` give `fn`: the part of a\n * handler's `ctx` that means something outside a method call. A job has no\n * caller, so `principal` is `null`. A `fn` that takes no parameter still\n * works.\n *\n * @example\n * await qd.run(async (ctx) => {\n * const ids = await renumberWithSql(projectId);\n * ctx.touch(\"task\", ids);\n * });\n */\nexport interface RunContext {\n /** `ctx.touch`: records rows the tracked client cannot see (raw SQL, cascades) in this run's unit of work. */\n readonly touch: BaseContext[\"touch\"];\n /** The dispatcher's logger, bound to this run's request id. */\n readonly log: Logger;\n readonly principal: null;\n}\n\n/** Options of `qd.run(fn, options)` and `dispatcher.run(fn, options)`. */\nexport interface RunOptions {\n /**\n * Run `fn` in a unit of work of its own even inside a method call or a\n * transaction: for background work a handler starts and does not await\n * (a push sent after the reply, pruning what it reports dead). Its writes\n * flush once `fn` settles, on their own, instead of joining the handler's\n * unit, which may have flushed long before (they would then flush as\n * ambient writes, with a development warning). A failed flush is logged.\n * Default `false`: inside an open unit of work or transaction, `fn` joins\n * it.\n *\n * @example\n * // in a handler, not awaited: the reply does not wait for the push\n * void qd.run(() => sendPushes(db, message), { detached: true }).catch((error) => {\n * ctx.log.error(\"Pushing the message failed\", { error: String(error) });\n * });\n */\n readonly detached?: boolean;\n}\n\n/** Builds the app's fields of `ctx` from the framework's: the `context` option of `initQuickdraw`. */\nexport type ContextExtender = (base: AnyContext) => object;\n\n/**\n * What the framework's kits (RFC 0003 section 12) know about the call a\n * `ctx` belongs to: the service whose method runs, and the dispatcher's\n * access policies and storage adapter. A kit's handlers are made before any\n * dispatcher exists, so they find these through `kitRuntimeOf(ctx)`. It is\n * never a member of `ctx`.\n */\nexport interface KitRuntime {\n readonly service: AnyService;\n /** `dispatcher.access`, and `resolve` for levels without service grants (a collection scope's). */\n readonly access: DispatcherAccess & Pick<PolicyEngine, \"resolve\">;\n readonly storage: StorageAdapter | undefined;\n /** How many sockets sit in a room, for the admin kit's subscriber counts. */\n readonly occupancy?: RoomOccupancy;\n /**\n * The revision a read made from now on is no older than (the search\n * kit's pages): the process's last one, or behind a cluster's counter the\n * counter's.\n */\n readonly claimRevision?: () => number | Promise<number>;\n /**\n * Runs `fn` in a detached unit of work of the dispatcher, as\n * `qd.run(fn, { detached: true })` does: a kit's work after its call (the\n * admin kit's `onCommitted`), whose writes flush on their own.\n */\n readonly runDetached?: (fn: () => unknown) => Promise<unknown>;\n}\n\n/** The sockets in a room (RFC 0003 section 6), as this process sees its rooms. */\nexport interface RoomOccupancy {\n /** This process's sockets in `room`: none without a server. */\n sockets(room: string): number;\n /**\n * `true` when this process sees every socket: its server has no cluster\n * adapter (Redis), or there is no server.\n */\n complete(): boolean;\n}\n\n/**\n * The per-call fields the dispatcher fills in. `touch` is the dispatcher's\n * (its tracked writes), `rooms` and `presence` its live data's, `dispatch`\n * its own dispatch function, which `ctx.services` calls through; a context\n * built without them gets a `touch` that does nothing, `rooms` that join\n * nothing and send nothing, a `presence` that sees nobody, and `services`\n * that throw `INTERNAL`. `kit` is kept beside the context, never on it.\n */\nexport type ContextFields = Pick<\n AnyContext,\n \"principal\" | \"signal\" | \"log\" | \"requestId\" | \"transport\" | \"socketId\" | \"mcp\"\n> &\n Partial<Pick<AnyContext, \"touch\" | \"rooms\" | \"presence\">> & {\n readonly kit?: KitRuntime;\n readonly dispatch?: Dispatch;\n };\n\nconst KIT_RUNTIMES = new WeakMap<object, KitRuntime>();\nconst SERVICE_CALLERS = new WeakMap<object, (signal: AbortSignal) => ContextServices>();\n\n/**\n * The kit runtime of the call `ctx` belongs to, or `undefined` for a\n * context no dispatcher built.\n */\nexport function kitRuntimeOf(ctx: object): KitRuntime | undefined {\n return KIT_RUNTIMES.get(ctx);\n}\n\nfunction withRuntime<Ctx extends object>(\n ctx: Ctx,\n runtime: KitRuntime | undefined,\n services: ((signal: AbortSignal) => ContextServices) | undefined,\n): Ctx {\n if (runtime !== undefined) {\n KIT_RUNTIMES.set(ctx, runtime);\n }\n if (services !== undefined) {\n SERVICE_CALLERS.set(ctx, services);\n }\n return ctx;\n}\n\n/** A signal that never aborts, for calls that cannot be cancelled. */\nexport const NEVER_ABORTED: AbortSignal = new AbortController().signal;\n\nfunction notAvailable(member: string): QuickdrawError {\n return new QuickdrawError(\n \"INTERNAL\",\n `${member} needs a dispatcher: it calls through the dispatcher that runs the method`,\n );\n}\n\nfunction untracked(): void {\n // Without tracked writes there is nothing to record.\n}\n\n// Names that inspection, serialization and test matchers read from any\n// object. They answer `undefined` so logging a `ctx` never throws.\nconst INSPECTED = new Set([\n \"then\",\n \"toJSON\",\n \"constructor\",\n \"toString\",\n \"valueOf\",\n \"asymmetricMatch\",\n \"$$typeof\",\n \"nodeType\",\n]);\n\nfunction unavailable(member: string): ContextServices {\n return new Proxy(Object.freeze({}), {\n get(_target, key) {\n if (typeof key === \"symbol\" || INSPECTED.has(key)) {\n return undefined;\n }\n throw notAvailable(`${member}.${key}`);\n },\n });\n}\n\nconst SERVICES: ContextServices = unavailable(\"ctx.services\");\n\n/** The `ctx.rooms` of a context no dispatcher built: no socket to join with, no server to send through. */\nconst NO_ROOMS: ContextRooms = Object.freeze({\n join: () => false,\n leave: ((_room: string, target?: unknown) =>\n target === undefined ? false : Promise.resolve()) as ContextRooms[\"leave\"],\n emit: untracked,\n emitToUser: untracked,\n size: () => 0,\n});\n\n/** The `ctx.presence` of a context no dispatcher built: no server, so nobody is online. */\nconst NO_PRESENCE: Presence = Object.freeze({\n isOnline: () => Promise.resolve(false),\n lastSeen: () => Promise.resolve(null),\n count: () => Promise.resolve(0),\n users: () => Promise.resolve([]),\n});\n\n/**\n * `ctx.services` for a signal: callers acting as `principal` through\n * `dispatch`, every call cancelled with the signal.\n */\nfunction servicesOf(\n dispatch: Dispatch | undefined,\n principal: Principal | null,\n): ((signal: AbortSignal) => ContextServices) | undefined {\n if (dispatch === undefined) {\n return undefined;\n }\n return (signal) => createCaller(() => dispatch, principal, { signal }) as ContextServices;\n}\n\n/**\n * Builds a call's `ctx`: the framework's fields, then the app's fields from\n * `extend`. The framework's fields win when the names collide.\n */\nexport function createContext(fields: ContextFields, extend?: ContextExtender): AnyContext {\n const { kit, dispatch, ...own } = fields;\n const services = servicesOf(dispatch, own.principal);\n const base: AnyContext = Object.freeze({\n ...own,\n touch: own.touch ?? untracked,\n services: services?.(own.signal) ?? SERVICES,\n rooms: own.rooms ?? NO_ROOMS,\n presence: own.presence ?? NO_PRESENCE,\n });\n if (extend === undefined) {\n return withRuntime(base, kit, services);\n }\n return withRuntime(Object.freeze({ ...extend(base), ...base }), kit, services);\n}\n\n/**\n * The same `ctx` with another signal: the one a handler run aborts. Its\n * `ctx.services` calls are cancelled with that signal.\n */\nexport function withSignal(ctx: AnyContext, signal: AbortSignal): AnyContext {\n const services = SERVICE_CALLERS.get(ctx);\n const next =\n services === undefined ? { ...ctx, signal } : { ...ctx, signal, services: services(signal) };\n return withRuntime(Object.freeze(next), KIT_RUNTIMES.get(ctx), services);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -22,11 +22,11 @@ import {
|
|
|
22
22
|
reorderInput,
|
|
23
23
|
unknownKeys,
|
|
24
24
|
withId
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-CDKG4TFA.js";
|
|
26
26
|
import {
|
|
27
27
|
ACCESS_LEVELS,
|
|
28
28
|
isAccessLevel
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-WVIRXYI4.js";
|
|
30
30
|
import {
|
|
31
31
|
isStandardSchema
|
|
32
32
|
} from "./chunk-47AEXVDM.js";
|
|
@@ -513,4 +513,4 @@ export {
|
|
|
513
513
|
sharingSpecOf,
|
|
514
514
|
sharing
|
|
515
515
|
};
|
|
516
|
-
//# sourceMappingURL=chunk-
|
|
516
|
+
//# sourceMappingURL=chunk-3JNMVB2V.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
describeError
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-DD4SKCNO.js";
|
|
4
4
|
import {
|
|
5
5
|
ANY_FIELD
|
|
6
6
|
} from "./chunk-H23KEFBA.js";
|
|
7
7
|
import {
|
|
8
8
|
consoleLogger
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-YSWH776Y.js";
|
|
10
10
|
|
|
11
11
|
// src/server/devWarnings.ts
|
|
12
12
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -802,4 +802,4 @@ export {
|
|
|
802
802
|
runBeforeAnyDispatcher,
|
|
803
803
|
createWriteTracker
|
|
804
804
|
};
|
|
805
|
-
//# sourceMappingURL=chunk-
|
|
805
|
+
//# sourceMappingURL=chunk-4DIQHASK.js.map
|