@beignet/core 0.0.47 → 0.0.49
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/CHANGELOG.md +33 -0
- package/README.md +81 -15
- package/dist/client/client.d.ts +0 -2
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +28 -25
- package/dist/client/client.js.map +1 -1
- package/dist/contracts/contract-builder.d.ts +7 -2
- package/dist/contracts/contract-builder.d.ts.map +1 -1
- package/dist/contracts/contract-builder.js +20 -2
- package/dist/contracts/contract-builder.js.map +1 -1
- package/dist/contracts/contract-group.d.ts.map +1 -1
- package/dist/contracts/contract-group.js +1 -0
- package/dist/contracts/contract-group.js.map +1 -1
- package/dist/contracts/contract-like.d.ts +2 -0
- package/dist/contracts/contract-like.d.ts.map +1 -1
- package/dist/contracts/contract-like.js +27 -1
- package/dist/contracts/contract-like.js.map +1 -1
- package/dist/contracts/index.d.ts +4 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +4 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/query-transport.d.ts +126 -0
- package/dist/contracts/query-transport.d.ts.map +1 -0
- package/dist/contracts/query-transport.js +406 -0
- package/dist/contracts/query-transport.js.map +1 -0
- package/dist/contracts/schema-shape.d.ts +11 -0
- package/dist/contracts/schema-shape.d.ts.map +1 -1
- package/dist/contracts/schema-shape.js +13 -0
- package/dist/contracts/schema-shape.js.map +1 -1
- package/dist/contracts/types.d.ts +5 -0
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/contracts/types.js.map +1 -1
- package/dist/openapi/index.d.ts +8 -0
- package/dist/openapi/index.d.ts.map +1 -1
- package/dist/openapi/index.js +79 -5
- package/dist/openapi/index.js.map +1 -1
- package/dist/outbox/index.d.ts +8 -5
- package/dist/outbox/index.d.ts.map +1 -1
- package/dist/outbox/index.js +17 -3
- package/dist/outbox/index.js.map +1 -1
- package/dist/ports/cache.d.ts +9 -1
- package/dist/ports/cache.d.ts.map +1 -1
- package/dist/ports/cache.js +20 -5
- package/dist/ports/cache.js.map +1 -1
- package/dist/ports/index.d.ts +1 -1
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +1 -1
- package/dist/ports/index.js.map +1 -1
- package/dist/providers/instrumentation.d.ts.map +1 -1
- package/dist/providers/instrumentation.js +14 -2
- package/dist/providers/instrumentation.js.map +1 -1
- package/dist/providers/metadata.d.ts +2 -0
- package/dist/providers/metadata.d.ts.map +1 -1
- package/dist/providers/metadata.js +78 -16
- package/dist/providers/metadata.js.map +1 -1
- package/dist/query-codec.d.ts +24 -0
- package/dist/query-codec.d.ts.map +1 -1
- package/dist/query-codec.js +207 -72
- package/dist/query-codec.js.map +1 -1
- package/dist/server/hooks/rate-limit.d.ts +16 -8
- package/dist/server/hooks/rate-limit.d.ts.map +1 -1
- package/dist/server/hooks/rate-limit.js +31 -17
- package/dist/server/hooks/rate-limit.js.map +1 -1
- package/dist/server/request-executor.d.ts.map +1 -1
- package/dist/server/request-executor.js +9 -9
- package/dist/server/request-executor.js.map +1 -1
- package/dist/server/request-preparation.d.ts.map +1 -1
- package/dist/server/request-preparation.js +11 -9
- package/dist/server/request-preparation.js.map +1 -1
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +2 -0
- package/dist/server/server.js.map +1 -1
- package/dist/server/use-case-route.d.ts +8 -5
- package/dist/server/use-case-route.d.ts.map +1 -1
- package/dist/server/use-case-route.js +44 -17
- package/dist/server/use-case-route.js.map +1 -1
- package/package.json +3 -3
- package/skills/app-architecture/SKILL.md +27 -1
- package/src/client/client.ts +29 -28
- package/src/contracts/contract-builder.ts +32 -2
- package/src/contracts/contract-group.ts +1 -0
- package/src/contracts/contract-like.ts +40 -1
- package/src/contracts/index.ts +23 -0
- package/src/contracts/query-transport.ts +697 -0
- package/src/contracts/schema-shape.ts +24 -0
- package/src/contracts/types.ts +5 -0
- package/src/openapi/index.ts +126 -2
- package/src/outbox/index.ts +26 -5
- package/src/ports/cache.ts +29 -7
- package/src/ports/index.ts +1 -1
- package/src/providers/instrumentation.ts +15 -2
- package/src/providers/metadata.ts +132 -16
- package/src/server/hooks/rate-limit.ts +50 -24
- package/src/server/request-executor.ts +17 -9
- package/src/server/request-preparation.ts +22 -9
- package/src/server/server.ts +2 -0
- package/src/server/use-case-route.ts +62 -23
- package/src/query-codec.ts +0 -130
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-case-route.d.ts","sourceRoot":"","sources":["../../src/server/use-case-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EACV,kBAAkB,EAClB,WAAW,EACX,cAAc,EACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,KAAK,EACV,iBAAiB,EACjB,OAAO,EACP,SAAS,EACT,YAAY,EACZ,SAAS,EACT,UAAU,EACV,SAAS,EACV,MAAM,WAAW,CAAC;AAEnB;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,WAAW,EAAE,gBAAgB,CAAC;IAC9B;;OAEG;IACH,YAAY,EAAE,gBAAgB,CAAC;IAC/B;;OAEG;IACH,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACxC,CAAC;AAEF,KAAK,eAAe,CAAC,EAAE,IAAI,EAAE,SAAS;IACpC,GAAG,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;CAC7E,GACG,GAAG,GACH,KAAK,CAAC;AAEV;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,EAAE,IAAI,EAAE,SAAS;IAC7C,GAAG,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,KAAK,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;CAC7E,GACG,KAAK,GACL,KAAK,CAAC;AAEV,KAAK,kBAAkB,CAAC,EAAE,IAAI,EAAE,SAAS;IACvC,GAAG,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;CAC7E,GACG,GAAG,GACH,KAAK,CAAC;AAEV,KAAK,qBAAqB,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,GAE1C,AADA,qHAAqH;AACrH,IAAI,GAAG,SAAS,GAChB,CAAC,SAAS,gBAAgB,GACxB,WAAW,CAAC,CAAC,CAAC,GACd,OAAO,CAAC;AAEd,KAAK,iBAAiB,CACpB,UAAU,EACV,OAAO,SAAS,MAAM,IACpB,OAAO,SAAS,MAAM,UAAU,GAChC,UAAU,CAAC,OAAO,CAAC,GACnB,GAAG,OAAO,EAAE,SAAS,MAAM,UAAU,GACnC,UAAU,CAAC,GAAG,OAAO,EAAE,CAAC,GACxB,KAAK,CAAC;AAEZ,KAAK,mBAAmB,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GACzD,OAAO,GACP,CAAC,SAAS,MAAM,GACd,qBAAqB,CAAC,iBAAiB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,GACvD,OAAO,CAAC;AAEd,KAAK,mBAAmB,CAAC,CAAC,IAAI,CAC5B,CAAC,SAAS,OAAO,GACb,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAClB,KAAK,CACV,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,GAC9B,CAAC,GACD,KAAK,CAAC;AAEV,KAAK,oBAAoB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAC9C;IACE;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB,GACD,CAAC,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,GAClC;IACE;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC;CACZ,GACD;IACE;;;OAGG;IACH,MAAM,EAAE,CAAC,CAAC;CACX,CAAC;AAER;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,kBAAkB,IACzD,oBAAoB,CAAC,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;AAEvD;;GAEG;AACH,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,kBAAkB,IAAI;IACjE;;OAEG;IACH,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACnB;;OAEG;IACH,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACrB;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;IACzB;;OAEG;IACH,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,CAAC,GAAG,EAAE,CAAC,SAAS,kBAAkB,EAAE,EAAE,IAAI;IACpE,GAAG;CACJ,SAAS,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,GAC3B,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,SAAS;IAC/B,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;CACpE,GACC,OAAO,GACP;IACE,eAAe,EAAE,sEAAsE,CAAC;CACzF,GACH;IACE,eAAe,EAAE,yDAAyD,CAAC;CAC5E,CAAC;AAEN,KAAK,iBAAiB,CACpB,UAAU,EACV,KAAK,SAAS,YAAY,EAC1B,CAAC,SAAS,kBAAkB,EAC5B,EAAE,SAAS,cAAc,EACzB,KAAK,IACH;IACF;;OAEG;IACH,QAAQ,EAAE,KAAK,CAAC;IAChB;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;OAEG;IACH,OAAO,EAAE,EAAE,GAAG,gBAAgB,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAClD
|
|
1
|
+
{"version":3,"file":"use-case-route.d.ts","sourceRoot":"","sources":["../../src/server/use-case-route.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,9 +15,10 @@ function isPlainObject(value) {
|
|
|
15
15
|
* Merges parsed query, body, and path objects into one input object. Path
|
|
16
16
|
* keys win all collisions, then body keys, then query keys. Headers are never
|
|
17
17
|
* merged: parsed headers include every raw request header, so merging them
|
|
18
|
-
* would poison the use case input.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* would poison the use case input. The route binder passes a sole declared
|
|
19
|
+
* input schema through unchanged when no other object input contains values;
|
|
20
|
+
* this merge handles every other default mapping. Routes that combine a
|
|
21
|
+
* non-object body with another source declare an explicit `input` mapper.
|
|
21
22
|
*/
|
|
22
23
|
export function defaultBinderInput(parts) {
|
|
23
24
|
return {
|
|
@@ -32,11 +33,30 @@ export function defaultBinderInput(parts) {
|
|
|
32
33
|
export function isUseCaseRouteDef(route) {
|
|
33
34
|
return route.useCase !== undefined && route.useCase !== null;
|
|
34
35
|
}
|
|
35
|
-
function
|
|
36
|
+
function computeSingleInput(contract, def) {
|
|
36
37
|
if (def.input)
|
|
37
|
-
return
|
|
38
|
-
const sources = [
|
|
39
|
-
|
|
38
|
+
return undefined;
|
|
39
|
+
const sources = [
|
|
40
|
+
{ source: "path", schema: contract.pathParams },
|
|
41
|
+
{
|
|
42
|
+
source: "query",
|
|
43
|
+
schema: contract.query,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
source: "body",
|
|
47
|
+
schema: contract.body,
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
const present = sources.filter((candidate) => candidate.schema !== null && candidate.schema !== undefined);
|
|
51
|
+
const single = present[0];
|
|
52
|
+
return present.length === 1 && single
|
|
53
|
+
? { source: single.source, schema: single.schema }
|
|
54
|
+
: undefined;
|
|
55
|
+
}
|
|
56
|
+
function canPassSingleInput(parts, source) {
|
|
57
|
+
return ["path", "query", "body"].every((candidate) => candidate === source ||
|
|
58
|
+
!isPlainObject(parts[candidate]) ||
|
|
59
|
+
Object.keys(parts[candidate]).length === 0);
|
|
40
60
|
}
|
|
41
61
|
function computeResponseExemption(contract, def, status) {
|
|
42
62
|
return def.useCase[USE_CASE_OUTPUT_VALIDATED_KEY] === true &&
|
|
@@ -59,18 +79,25 @@ export function createUseCaseRouteHandler(contract, def) {
|
|
|
59
79
|
? "no responses"
|
|
60
80
|
: "zero or multiple 2xx responses"}. Declare exactly one 2xx response or pass an explicit status.`);
|
|
61
81
|
}
|
|
62
|
-
const
|
|
63
|
-
const trustedRun =
|
|
82
|
+
const singleInput = computeSingleInput(contract, def);
|
|
83
|
+
const trustedRun = singleInput?.schema === def.useCase.inputSchema
|
|
64
84
|
? def.useCase[USE_CASE_TRUSTED_RUN_KEY]
|
|
65
85
|
: undefined;
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
input
|
|
72
|
-
|
|
73
|
-
|
|
86
|
+
const handler = async ({ ctx, path, query, headers, body, }) => {
|
|
87
|
+
const parts = { path, query, headers, body };
|
|
88
|
+
const passSingle = singleInput !== undefined &&
|
|
89
|
+
canPassSingleInput(parts, singleInput.source);
|
|
90
|
+
const input = def.input
|
|
91
|
+
? def.input(parts)
|
|
92
|
+
: passSingle
|
|
93
|
+
? parts[singleInput.source]
|
|
94
|
+
: defaultBinderInput(parts);
|
|
95
|
+
const run = passSingle && trustedRun ? trustedRun : def.useCase.run;
|
|
96
|
+
return {
|
|
97
|
+
status,
|
|
98
|
+
body: await run.call(def.useCase, { ctx, input }),
|
|
99
|
+
};
|
|
100
|
+
};
|
|
74
101
|
return {
|
|
75
102
|
handler,
|
|
76
103
|
responseValidationExemptStatus: computeResponseExemption(contract, def, status),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-case-route.js","sourceRoot":"","sources":["../../src/server/use-case-route.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"use-case-route.js","sourceRoot":"","sources":["../../src/server/use-case-route.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beignet/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.49",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Core framework primitives for Beignet",
|
|
6
6
|
"exports": {
|
|
@@ -199,7 +199,7 @@
|
|
|
199
199
|
"access": "public"
|
|
200
200
|
},
|
|
201
201
|
"engines": {
|
|
202
|
-
"node": ">=
|
|
202
|
+
"node": ">=22.12.0"
|
|
203
203
|
},
|
|
204
204
|
"dependencies": {
|
|
205
205
|
"@standard-schema/spec": "^1.0.0"
|
|
@@ -214,7 +214,7 @@
|
|
|
214
214
|
},
|
|
215
215
|
"devDependencies": {
|
|
216
216
|
"@types/bun": "^1.3.13",
|
|
217
|
-
"@types/node": "^
|
|
217
|
+
"@types/node": "^22.0.0",
|
|
218
218
|
"openapi-fetch": "^0.17.0",
|
|
219
219
|
"openapi-typescript": "^7.13.0",
|
|
220
220
|
"typescript": "^5.3.0",
|
|
@@ -82,7 +82,11 @@ themselves.
|
|
|
82
82
|
Use `@beignet/core/contracts` and keep shared DTOs in `schemas.ts`.
|
|
83
83
|
|
|
84
84
|
```ts
|
|
85
|
-
import {
|
|
85
|
+
import {
|
|
86
|
+
defineContractGroup,
|
|
87
|
+
defineQueryTransport,
|
|
88
|
+
query,
|
|
89
|
+
} from "@beignet/core/contracts";
|
|
86
90
|
import { z } from "zod";
|
|
87
91
|
import { errors } from "@/features/shared/errors";
|
|
88
92
|
|
|
@@ -100,10 +104,21 @@ export const getProject = projects
|
|
|
100
104
|
.pathParams(z.object({ id: z.uuid() }))
|
|
101
105
|
.errors({ ProjectNotFound: errors.ProjectNotFound })
|
|
102
106
|
.responses({ 200: projectSchema });
|
|
107
|
+
|
|
108
|
+
export const listProjects = projects
|
|
109
|
+
.get("/")
|
|
110
|
+
.query(
|
|
111
|
+
z.object({ archived: z.boolean().optional() }),
|
|
112
|
+
defineQueryTransport({ archived: query.boolean() }),
|
|
113
|
+
)
|
|
114
|
+
.responses({ 200: z.array(projectSchema) });
|
|
103
115
|
```
|
|
104
116
|
|
|
105
117
|
If a route-backed use case throws `appError("ProjectNotFound")`, the matching
|
|
106
118
|
contract should declare `ProjectNotFound` with `.errors(...)`.
|
|
119
|
+
Every query schema needs an explicit transport. The schema owns logical input
|
|
120
|
+
validation and transforms; the transport owns client, server, and OpenAPI URL
|
|
121
|
+
serialization.
|
|
107
122
|
|
|
108
123
|
## Use Cases
|
|
109
124
|
|
|
@@ -228,6 +243,13 @@ Register workflow artifacts explicitly:
|
|
|
228
243
|
`server/notifications.ts`, then add that job to every worker/outbox registry
|
|
229
244
|
- seeds through the app's seed entrypoint, usually `server/seed.ts`
|
|
230
245
|
|
|
246
|
+
Outbox registration describes what a drain may deliver; it does not install
|
|
247
|
+
delivery transports. A registry containing events requires
|
|
248
|
+
`ctx.ports.eventBus`, and one containing jobs requires `ctx.ports.jobs`. Bind
|
|
249
|
+
those ports directly or defer them to providers before exposing a drain.
|
|
250
|
+
`drainOutbox(...)` rejects missing transports before claiming a batch, so
|
|
251
|
+
wiring failures do not consume delivery attempts.
|
|
252
|
+
|
|
231
253
|
Notification channels run independently and return per-channel outcomes. Use
|
|
232
254
|
the inline dispatcher for immediate delivery and the queued dispatcher/provider
|
|
233
255
|
for one independently retryable job per channel. Preferences are an optional
|
|
@@ -278,6 +300,10 @@ needed; use `false` only when reporting may intentionally block the boundary.
|
|
|
278
300
|
|
|
279
301
|
## Runtime Safety
|
|
280
302
|
|
|
303
|
+
- Metadata-driven rate limits namespace default global, IP, and user buckets by
|
|
304
|
+
contract name. User scope fails closed unless route hooks resolve a user
|
|
305
|
+
actor. Custom `key` and `earlyKey` callbacks own the complete key, so include
|
|
306
|
+
route identity unless cross-route aggregation is deliberate.
|
|
281
307
|
- HTTP idempotency defaults to the current actor and includes the current
|
|
282
308
|
tenant when one exists. The default actor scope fails closed when the
|
|
283
309
|
required identity is missing. Use
|
package/src/client/client.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BEIGNET_ERROR_OWNER_HEADER,
|
|
3
3
|
type ContractLike,
|
|
4
|
+
encodeQueryTransport,
|
|
4
5
|
getContractHeaderSchemas,
|
|
5
6
|
type HttpContractConfig,
|
|
6
7
|
methodSupportsRequestBody,
|
|
7
8
|
parsePathTemplate,
|
|
9
|
+
QueryTransportError,
|
|
8
10
|
type ResolveContract,
|
|
9
11
|
resolveContract,
|
|
10
12
|
type StandardErrorResponseBody,
|
|
@@ -12,7 +14,6 @@ import {
|
|
|
12
14
|
type StandardSchemaV1,
|
|
13
15
|
} from "../contracts/index.js";
|
|
14
16
|
import { isErrorResponseBody, SchemaValidationError } from "../errors/index.js";
|
|
15
|
-
import { encodeQueryValue } from "../query-codec.js";
|
|
16
17
|
import type {
|
|
17
18
|
CallArgs,
|
|
18
19
|
ClientConfig,
|
|
@@ -960,15 +961,28 @@ export class Endpoint<
|
|
|
960
961
|
.join("/")}`;
|
|
961
962
|
|
|
962
963
|
// Add query parameters
|
|
963
|
-
let queryToSerialize = query;
|
|
964
964
|
if (query) {
|
|
965
|
+
if (!this.contract.queryTransport) {
|
|
966
|
+
throw new ContractError({
|
|
967
|
+
source: "contract",
|
|
968
|
+
code: "INVALID_QUERY_TRANSPORT",
|
|
969
|
+
message: `Contract "${this.contract.name}" does not declare a query transport.`,
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
let params: URLSearchParams | undefined;
|
|
973
|
+
let transportFailure: { error: unknown } | undefined;
|
|
974
|
+
try {
|
|
975
|
+
// Serialize before validation so even a non-conforming Standard Schema
|
|
976
|
+
// that mutates its input cannot turn validation into a wire transform.
|
|
977
|
+
params = encodeQueryTransport(this.contract.queryTransport, query);
|
|
978
|
+
} catch (error) {
|
|
979
|
+
transportFailure = { error };
|
|
980
|
+
}
|
|
981
|
+
|
|
965
982
|
// Validate query params if schema exists and validation is enabled
|
|
966
983
|
if (this.config.validateInput && this.contract.query) {
|
|
967
984
|
try {
|
|
968
|
-
|
|
969
|
-
this.contract.query,
|
|
970
|
-
query,
|
|
971
|
-
)) as QueryParams;
|
|
985
|
+
await validateSchema(this.contract.query, query);
|
|
972
986
|
} catch (err) {
|
|
973
987
|
if (err instanceof SchemaValidationError) {
|
|
974
988
|
throw this.createError({
|
|
@@ -981,14 +995,17 @@ export class Endpoint<
|
|
|
981
995
|
}
|
|
982
996
|
}
|
|
983
997
|
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
998
|
+
if (transportFailure) {
|
|
999
|
+
if (transportFailure.error instanceof QueryTransportError) {
|
|
1000
|
+
throw this.createError({
|
|
1001
|
+
code: "INVALID_QUERY_PARAM",
|
|
1002
|
+
message: "Query transport encoding failed",
|
|
1003
|
+
details: transportFailure.error.issues,
|
|
1004
|
+
});
|
|
989
1005
|
}
|
|
1006
|
+
throw transportFailure.error;
|
|
990
1007
|
}
|
|
991
|
-
const queryString = params
|
|
1008
|
+
const queryString = params?.toString() ?? "";
|
|
992
1009
|
if (queryString) {
|
|
993
1010
|
url += `?${queryString}`;
|
|
994
1011
|
}
|
|
@@ -1002,22 +1019,6 @@ export class Endpoint<
|
|
|
1002
1019
|
return baseUrl + url;
|
|
1003
1020
|
}
|
|
1004
1021
|
|
|
1005
|
-
private serializeQueryParam(key: string, value: unknown): string {
|
|
1006
|
-
try {
|
|
1007
|
-
return encodeQueryValue(value);
|
|
1008
|
-
} catch {
|
|
1009
|
-
throw this.invalidQueryParam(key, "contains a non-serializable value");
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
private invalidQueryParam(key: string, reason: string): ContractError {
|
|
1014
|
-
return new ContractError({
|
|
1015
|
-
source: "client",
|
|
1016
|
-
code: "INVALID_QUERY_PARAM",
|
|
1017
|
-
message: `Query parameter "${key}" ${reason}. Use primitive values, Dates, JSON-serializable objects, or arrays of those values.`,
|
|
1018
|
-
});
|
|
1019
|
-
}
|
|
1020
|
-
|
|
1021
1022
|
/**
|
|
1022
1023
|
* Build request headers
|
|
1023
1024
|
*/
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
mergeCatalogErrors,
|
|
6
6
|
responsesFromErrors,
|
|
7
7
|
} from "./catalog-errors.js";
|
|
8
|
+
import { assertContractQueryTransport } from "./contract-like.js";
|
|
8
9
|
import {
|
|
9
10
|
assertValidContractDeprecation,
|
|
10
11
|
assertValidContractLifecycle,
|
|
@@ -13,6 +14,10 @@ import {
|
|
|
13
14
|
import { mergeContractMeta } from "./metadata.js";
|
|
14
15
|
import type { OpenAPIOperationMeta } from "./openapi-meta.js";
|
|
15
16
|
import { parsePathTemplate } from "./path-template.js";
|
|
17
|
+
import type {
|
|
18
|
+
QueryTransport,
|
|
19
|
+
QueryTransportCompatibility,
|
|
20
|
+
} from "./query-transport.js";
|
|
16
21
|
import type {
|
|
17
22
|
BodyHttpMethod,
|
|
18
23
|
ContractErrorResponses,
|
|
@@ -56,6 +61,7 @@ export class ContractBuilder<
|
|
|
56
61
|
private readonly _path: TPath;
|
|
57
62
|
private readonly _pathParams: TPathParams;
|
|
58
63
|
private readonly _query: TQuery;
|
|
64
|
+
private readonly _queryTransport: QueryTransport | null;
|
|
59
65
|
private readonly _body: TBody;
|
|
60
66
|
private readonly _headers: THeaders;
|
|
61
67
|
private readonly _responses: TResponses;
|
|
@@ -74,6 +80,7 @@ export class ContractBuilder<
|
|
|
74
80
|
>,
|
|
75
81
|
) {
|
|
76
82
|
assertValidContractLifecycle(config);
|
|
83
|
+
assertContractQueryTransport(config);
|
|
77
84
|
if (config.body && !methodSupportsRequestBody(config.method)) {
|
|
78
85
|
throw new Error(
|
|
79
86
|
`Request bodies are not supported for ${config.method} contracts. Use POST, PUT, or PATCH for contract request bodies.`,
|
|
@@ -87,6 +94,7 @@ export class ContractBuilder<
|
|
|
87
94
|
this._path = config.path;
|
|
88
95
|
this._pathParams = config.pathParams;
|
|
89
96
|
this._query = config.query;
|
|
97
|
+
this._queryTransport = config.queryTransport ?? null;
|
|
90
98
|
this._body = config.body;
|
|
91
99
|
this._headers = config.headers ?? (null as THeaders);
|
|
92
100
|
this._responses = config.responses;
|
|
@@ -152,6 +160,7 @@ export class ContractBuilder<
|
|
|
152
160
|
path: this._path,
|
|
153
161
|
pathParams: this._pathParams,
|
|
154
162
|
query: this._query,
|
|
163
|
+
queryTransport: this._queryTransport,
|
|
155
164
|
headers: this._headers,
|
|
156
165
|
body: this._body,
|
|
157
166
|
responses: this._responses,
|
|
@@ -186,6 +195,7 @@ export class ContractBuilder<
|
|
|
186
195
|
path: this._path,
|
|
187
196
|
pathParams: schema as unknown as TNewPathParams,
|
|
188
197
|
query: this._query,
|
|
198
|
+
queryTransport: this._queryTransport,
|
|
189
199
|
headers: this._headers,
|
|
190
200
|
body: this._body,
|
|
191
201
|
responses: this._responses,
|
|
@@ -194,10 +204,21 @@ export class ContractBuilder<
|
|
|
194
204
|
}
|
|
195
205
|
|
|
196
206
|
/**
|
|
197
|
-
* Attach a schema for
|
|
207
|
+
* Attach a query schema and the deterministic URL transport for its input.
|
|
208
|
+
*
|
|
209
|
+
* The schema owns validation, defaults, and transforms. The transport owns
|
|
210
|
+
* client encoding, server decoding, and OpenAPI serialization.
|
|
198
211
|
*/
|
|
199
|
-
query<
|
|
212
|
+
query<
|
|
213
|
+
TNewQuery extends StandardSchemaV1,
|
|
214
|
+
const TTransport extends QueryTransport,
|
|
215
|
+
>(
|
|
200
216
|
schema: TNewQuery,
|
|
217
|
+
transport: TTransport &
|
|
218
|
+
QueryTransportCompatibility<
|
|
219
|
+
StandardSchemaV1.InferInput<TNewQuery>,
|
|
220
|
+
TTransport
|
|
221
|
+
>,
|
|
201
222
|
): ContractBuilder<
|
|
202
223
|
TMethod,
|
|
203
224
|
TPathParams,
|
|
@@ -217,6 +238,7 @@ export class ContractBuilder<
|
|
|
217
238
|
path: this._path,
|
|
218
239
|
pathParams: this._pathParams,
|
|
219
240
|
query: schema as unknown as TNewQuery,
|
|
241
|
+
queryTransport: transport,
|
|
220
242
|
headers: this._headers,
|
|
221
243
|
body: this._body,
|
|
222
244
|
responses: this._responses,
|
|
@@ -270,6 +292,7 @@ export class ContractBuilder<
|
|
|
270
292
|
path: self._path,
|
|
271
293
|
pathParams: self._pathParams,
|
|
272
294
|
query: self._query,
|
|
295
|
+
queryTransport: self._queryTransport,
|
|
273
296
|
headers: self._headers,
|
|
274
297
|
body: schema as unknown as TNewBody,
|
|
275
298
|
responses: self._responses,
|
|
@@ -315,6 +338,7 @@ export class ContractBuilder<
|
|
|
315
338
|
path: this._path,
|
|
316
339
|
pathParams: this._pathParams,
|
|
317
340
|
query: this._query,
|
|
341
|
+
queryTransport: this._queryTransport,
|
|
318
342
|
headers: [
|
|
319
343
|
...existingHeaders,
|
|
320
344
|
schema,
|
|
@@ -360,6 +384,7 @@ export class ContractBuilder<
|
|
|
360
384
|
path: this._path,
|
|
361
385
|
pathParams: this._pathParams,
|
|
362
386
|
query: this._query,
|
|
387
|
+
queryTransport: this._queryTransport,
|
|
363
388
|
headers: this._headers,
|
|
364
389
|
body: this._body,
|
|
365
390
|
responses: {
|
|
@@ -410,6 +435,7 @@ export class ContractBuilder<
|
|
|
410
435
|
path: this._path,
|
|
411
436
|
pathParams: this._pathParams,
|
|
412
437
|
query: this._query,
|
|
438
|
+
queryTransport: this._queryTransport,
|
|
413
439
|
headers: this._headers,
|
|
414
440
|
body: this._body,
|
|
415
441
|
responses: {
|
|
@@ -456,6 +482,7 @@ export class ContractBuilder<
|
|
|
456
482
|
path: this._path,
|
|
457
483
|
pathParams: this._pathParams,
|
|
458
484
|
query: this._query,
|
|
485
|
+
queryTransport: this._queryTransport,
|
|
459
486
|
headers: this._headers,
|
|
460
487
|
body: this._body,
|
|
461
488
|
responses: this._responses,
|
|
@@ -488,6 +515,7 @@ export class ContractBuilder<
|
|
|
488
515
|
path: this._path,
|
|
489
516
|
pathParams: this._pathParams,
|
|
490
517
|
query: this._query,
|
|
518
|
+
queryTransport: this._queryTransport,
|
|
491
519
|
headers: this._headers,
|
|
492
520
|
body: this._body,
|
|
493
521
|
responses: this._responses,
|
|
@@ -519,6 +547,7 @@ export class ContractBuilder<
|
|
|
519
547
|
path: this._path,
|
|
520
548
|
pathParams: this._pathParams,
|
|
521
549
|
query: this._query,
|
|
550
|
+
queryTransport: this._queryTransport,
|
|
522
551
|
headers: this._headers,
|
|
523
552
|
body: this._body,
|
|
524
553
|
responses: this._responses,
|
|
@@ -588,6 +617,7 @@ export function defineContract<
|
|
|
588
617
|
path: options.path,
|
|
589
618
|
pathParams: null,
|
|
590
619
|
query: null,
|
|
620
|
+
queryTransport: null,
|
|
591
621
|
headers: null,
|
|
592
622
|
body: null,
|
|
593
623
|
responses: {},
|
|
@@ -1,5 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
compareQueryTransportFields,
|
|
3
|
+
formatQueryTransportMismatch,
|
|
4
|
+
getObjectSchemaShape,
|
|
5
|
+
} from "./schema-shape.js";
|
|
1
6
|
import type { HttpContractConfig } from "./types.js";
|
|
2
7
|
|
|
8
|
+
/** Assert that a plain contract config declares one transport per query. */
|
|
9
|
+
export function assertContractQueryTransport(
|
|
10
|
+
contract: HttpContractConfig,
|
|
11
|
+
): void {
|
|
12
|
+
if (contract.query && !contract.queryTransport) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
`Contract "${contract.name}" declares a query schema without a query transport. Pass defineQueryTransport(...) as the second argument to .query(...).`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
if (!contract.query && contract.queryTransport) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Contract "${contract.name}" declares a query transport without a query schema.`,
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (contract.query && contract.queryTransport) {
|
|
23
|
+
const shape = getObjectSchemaShape(contract.query);
|
|
24
|
+
if (!shape) return;
|
|
25
|
+
|
|
26
|
+
const schemaKeys = Object.keys(shape);
|
|
27
|
+
const transportKeys = Object.keys(contract.queryTransport.fields);
|
|
28
|
+
if (!compareQueryTransportFields({ schemaKeys, transportKeys })) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
formatQueryTransportMismatch({
|
|
31
|
+
contractName: contract.name,
|
|
32
|
+
schemaKeys,
|
|
33
|
+
transportKeys,
|
|
34
|
+
}),
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
3
40
|
/**
|
|
4
41
|
* Contract input accepted by APIs that can unwrap builders.
|
|
5
42
|
*/
|
|
@@ -25,5 +62,7 @@ export type ResolveContract<T> = T extends { config: infer C }
|
|
|
25
62
|
export function resolveContract<T extends ContractLike>(
|
|
26
63
|
c: T,
|
|
27
64
|
): ResolveContract<T> {
|
|
28
|
-
|
|
65
|
+
const contract = ("config" in c ? c.config : c) as ResolveContract<T>;
|
|
66
|
+
assertContractQueryTransport(contract);
|
|
67
|
+
return contract;
|
|
29
68
|
}
|
package/src/contracts/index.ts
CHANGED
|
@@ -55,6 +55,29 @@ export {
|
|
|
55
55
|
type PathTemplateSegment,
|
|
56
56
|
parsePathTemplate,
|
|
57
57
|
} from "./path-template.js";
|
|
58
|
+
/**
|
|
59
|
+
* Query transport declarations shared by servers, clients, and OpenAPI.
|
|
60
|
+
*/
|
|
61
|
+
export {
|
|
62
|
+
decodeQueryTransport,
|
|
63
|
+
defineQueryTransport,
|
|
64
|
+
encodeQueryTransport,
|
|
65
|
+
type QueryArrayTransport,
|
|
66
|
+
type QueryDeepObjectFields,
|
|
67
|
+
type QueryDeepObjectTransport,
|
|
68
|
+
type QueryEmptyBehavior,
|
|
69
|
+
type QueryFieldTransport,
|
|
70
|
+
type QueryFieldTransportInput,
|
|
71
|
+
type QueryScalarTransport,
|
|
72
|
+
type QueryTransport,
|
|
73
|
+
type QueryTransportCompatibility,
|
|
74
|
+
QueryTransportError,
|
|
75
|
+
type QueryTransportFields,
|
|
76
|
+
type QueryTransportInput,
|
|
77
|
+
type QueryTransportIssue,
|
|
78
|
+
query,
|
|
79
|
+
queryTransportSchema,
|
|
80
|
+
} from "./query-transport.js";
|
|
58
81
|
/**
|
|
59
82
|
* Rate limit metadata types for contracts.
|
|
60
83
|
*/
|