@nxgt/openapi-httpyz 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +43 -31
- package/dist/client/create-openapi-client.d.ts +7 -6
- package/dist/client/create-openapi-client.d.ts.map +1 -1
- package/dist/client/types.d.ts +12 -11
- package/dist/client/types.d.ts.map +1 -1
- package/dist/index.js +8 -4
- package/dist/index.js.map +3 -3
- package/package.json +8 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Steve Tsala
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ typed from the table alone:
|
|
|
58
58
|
- `api.get` offers the paths that have a GET operation, and takes what the
|
|
59
59
|
operation at the chosen path takes.
|
|
60
60
|
- The client has only the methods the spec has an operation for: no `trace`
|
|
61
|
-
on a spec without a TRACE operation.
|
|
61
|
+
on a spec without a TRACE operation, in its types or at runtime.
|
|
62
62
|
|
|
63
63
|
The types may also be given, as a table generated before
|
|
64
64
|
`@nxgt/openapi-codegen` carried them requires:
|
|
@@ -193,28 +193,29 @@ where the spec says `minimum: 1`, or a reply from a server that drifted.
|
|
|
193
193
|
schema, as [`@nxgt/openapi-hono`](https://www.npmjs.com/package/@nxgt/openapi-hono)
|
|
194
194
|
checks its own with `validateResponses`.
|
|
195
195
|
|
|
196
|
+
Both are checked by default, as a plain call of the client checks a declared
|
|
197
|
+
reply. Turn off what you do not want:
|
|
198
|
+
|
|
196
199
|
```ts
|
|
197
|
-
createOpenApiClient(http, operations, { validate: { request:
|
|
200
|
+
createOpenApiClient(http, operations, { validate: { request: false } }); // the reply only
|
|
201
|
+
createOpenApiClient(http, operations, { validate: false, decode: false }); // nothing
|
|
198
202
|
```
|
|
199
203
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
`decode` returns each reply as its schema outputs it, which differs from what
|
|
205
|
-
JSON carries once the spec is generated with `dates: 'date'`: a date-time is
|
|
206
|
-
a `Date`. The client's replies are typed so:
|
|
204
|
+
`decode`, also on by default, returns each reply as its schema outputs it,
|
|
205
|
+
which differs from what JSON carries once the spec is generated with
|
|
206
|
+
`dates: 'date'`: a date-time is a `Date`. The client's replies are typed so:
|
|
207
207
|
|
|
208
208
|
```ts
|
|
209
|
-
const api = createOpenApiClient(http, operations
|
|
209
|
+
const api = createOpenApiClient(http, operations);
|
|
210
210
|
const employee = unwrap(await api.get('/employees/{id}', { param: { id } }), 200);
|
|
211
211
|
employee.hiredAt; // Date
|
|
212
212
|
```
|
|
213
213
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
`
|
|
214
|
+
Decoding validates the reply, whatever `validate` says. `decode: false`
|
|
215
|
+
returns each reply, and types it, as JSON carries it. With the types given,
|
|
216
|
+
a third type argument says the client does not decode:
|
|
217
|
+
`createOpenApiClient<ClientOperations, OperationsByRoute, false>`, which does
|
|
218
|
+
not compile without `decode: false`.
|
|
218
219
|
|
|
219
220
|
## API
|
|
220
221
|
|
|
@@ -227,17 +228,17 @@ and `watchFeed`, an event stream, at `GET /feed`.
|
|
|
227
228
|
#### createOpenApiClient
|
|
228
229
|
|
|
229
230
|
```ts
|
|
230
|
-
// With decode:
|
|
231
|
+
// With decode: false, the replies are typed as JSON carries them
|
|
231
232
|
function createOpenApiClient<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>>(
|
|
232
233
|
http: HttpClient,
|
|
233
234
|
operations: OperationTable<Ops>,
|
|
234
|
-
options: OpenApiOptions & { readonly decode:
|
|
235
|
-
): OpenApiClient<Ops, Routes,
|
|
235
|
+
options: OpenApiOptions & { readonly decode: false },
|
|
236
|
+
): OpenApiClient<Ops, Routes, false>;
|
|
236
237
|
|
|
237
238
|
function createOpenApiClient<
|
|
238
239
|
Ops extends OperationsShape<Ops>,
|
|
239
240
|
Routes = RoutesOf<Ops>,
|
|
240
|
-
Decoded extends boolean =
|
|
241
|
+
Decoded extends boolean = true,
|
|
241
242
|
>(
|
|
242
243
|
http: HttpClient,
|
|
243
244
|
operations: OperationTable<Ops>,
|
|
@@ -247,16 +248,18 @@ function createOpenApiClient<
|
|
|
247
248
|
|
|
248
249
|
Binds the generated `operations` table onto `http`, a client of
|
|
249
250
|
`createHttpClient()` or one of its groups. `Ops` is inferred from the table;
|
|
250
|
-
`Routes` defaults to `RoutesOf<Ops>`; `Decoded` is `
|
|
251
|
-
is passed. See [Setup](#setup) and [Validating and decoding](#validating-and-decoding).
|
|
251
|
+
`Routes` defaults to `RoutesOf<Ops>`; `Decoded` is `false` when
|
|
252
|
+
`decode: false` is passed, and `true` otherwise. See [Setup](#setup) and [Validating and decoding](#validating-and-decoding).
|
|
252
253
|
|
|
253
254
|
| Option | Type | Default | Description |
|
|
254
255
|
| --- | --- | --- | --- |
|
|
255
|
-
| `validate` | `boolean \| { request?: boolean; response?: boolean }` |
|
|
256
|
-
| `decode` | `true \| false` | `
|
|
256
|
+
| `validate` | `boolean \| { request?: boolean; response?: boolean }` | both | Checks with the spec's schemas, throwing a `ValidationError`: the request before it is sent, the reply before it is returned. `true` is both, `false` neither |
|
|
257
|
+
| `decode` | `true \| false` | `true` | Returns each reply as its schema outputs it, and types it so, validating it whatever `validate` says. `false` returns it as JSON carries it. A literal: a `boolean` variable does not compile, since the replies' type depends on it |
|
|
257
258
|
|
|
258
259
|
Returns an [`OpenApiClient`](#openapiclient). It throws nothing itself: an
|
|
259
|
-
unknown `operationId`
|
|
260
|
+
unknown `operationId` fails the call made with it, and a path with no
|
|
261
|
+
operation for its method rejects with a `ClientError`,
|
|
262
|
+
`GET /x: the spec has no operation at it`.
|
|
260
263
|
|
|
261
264
|
### The client
|
|
262
265
|
|
|
@@ -387,21 +390,21 @@ does. `PathMethods<ClientOperations>` has `get` and `post` on the example spec.
|
|
|
387
390
|
|
|
388
391
|
| Field | Type | Description |
|
|
389
392
|
| --- | --- | --- |
|
|
390
|
-
| `validate` | `boolean \| { readonly request?: boolean; readonly response?: boolean }` | Checks the request, the reply,
|
|
393
|
+
| `validate` | `boolean \| { readonly request?: boolean; readonly response?: boolean }` | Checks the request, the reply, both (`true`) or neither (`false`). Default: both |
|
|
391
394
|
|
|
392
395
|
The options of [`createOpenApiClient`](#createopenapiclient), beside `decode`.
|
|
393
396
|
|
|
394
397
|
#### OpenApiArgs
|
|
395
398
|
|
|
396
399
|
```ts
|
|
397
|
-
type OpenApiArgs<Decoded extends boolean> = Decoded extends
|
|
398
|
-
? [options: OpenApiOptions & { readonly decode:
|
|
399
|
-
: [options?: OpenApiOptions & { readonly decode?:
|
|
400
|
+
type OpenApiArgs<Decoded extends boolean> = Decoded extends false
|
|
401
|
+
? [options: OpenApiOptions & { readonly decode: false }]
|
|
402
|
+
: [options?: OpenApiOptions & { readonly decode?: true }];
|
|
400
403
|
```
|
|
401
404
|
|
|
402
|
-
The options argument of `createOpenApiClient()`, required with
|
|
403
|
-
when `Decoded` is `
|
|
404
|
-
`[options?: OpenApiOptions & { readonly decode?:
|
|
405
|
+
The options argument of `createOpenApiClient()`, required with
|
|
406
|
+
`decode: false` when `Decoded` is `false`. `OpenApiArgs<true>` resolves to
|
|
407
|
+
`[options?: OpenApiOptions & { readonly decode?: true }]`.
|
|
405
408
|
|
|
406
409
|
#### OperationInit
|
|
407
410
|
|
|
@@ -576,7 +579,16 @@ A media type of a `RuntimeOperation`'s `body` or `responses`.
|
|
|
576
579
|
|
|
577
580
|
## Traps
|
|
578
581
|
|
|
579
|
-
- **
|
|
582
|
+
- **Decoding returns what the schema outputs**, and it is on by default: keys
|
|
583
|
+
the spec does not declare are dropped, unless the spec was generated to
|
|
584
|
+
keep them, and a reply the spec refuses throws a `ValidationError`, even
|
|
585
|
+
with `validate: false`. `decode: false` takes the reply at its word.
|
|
586
|
+
- **An error reply is checked too.** A 400 declared with a schema that does
|
|
587
|
+
not describe what the server sends, such as the validation body of
|
|
588
|
+
`@nxgt/openapi-hono`, `{ status, message, timestamp, issues }`, throws a
|
|
589
|
+
`ValidationError` instead of returning the 400. Declare the body the server
|
|
590
|
+
sends, or pass `decode: false` and `validate: { response: false }`.
|
|
591
|
+
- **With `decode: false`, a reply is typed as JSON carries it**: with
|
|
580
592
|
`dates: 'date'`, a date-time is a string.
|
|
581
593
|
- **A request is typed as JSON carries it, whatever `decode` says.** With
|
|
582
594
|
`dates: 'date'`, a date-time in a body or a query is still typed as a
|
|
@@ -17,12 +17,13 @@ import type { OpenApiArgs, OpenApiClient, OpenApiOptions, OperationsShape, Opera
|
|
|
17
17
|
* if (reply.status === 200) reply.data.name;
|
|
18
18
|
* ```
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
* typed so.
|
|
22
|
-
*
|
|
20
|
+
* It checks the request and the reply, and returns each reply as its schema
|
|
21
|
+
* outputs it, typed so. `decode: false` returns it as JSON carries it. The
|
|
22
|
+
* types may also be given: `createOpenApiClient<ClientOperations,
|
|
23
|
+
* OperationsByRoute, false>`, whose `false` then requires `decode: false`.
|
|
23
24
|
*/
|
|
24
25
|
export declare function createOpenApiClient<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>>(http: HttpClient, operations: OperationTable<Ops>, options: OpenApiOptions & {
|
|
25
|
-
readonly decode:
|
|
26
|
-
}): OpenApiClient<Ops, Routes,
|
|
27
|
-
export declare function createOpenApiClient<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>, Decoded extends boolean =
|
|
26
|
+
readonly decode: false;
|
|
27
|
+
}): OpenApiClient<Ops, Routes, false>;
|
|
28
|
+
export declare function createOpenApiClient<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>, Decoded extends boolean = true>(http: HttpClient, operations: OperationTable<Ops>, ...[given]: OpenApiArgs<Decoded>): OpenApiClient<Ops, Routes, Decoded>;
|
|
28
29
|
//# sourceMappingURL=create-openapi-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-openapi-client.d.ts","sourceRoot":"","sources":["../../src/client/create-openapi-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,
|
|
1
|
+
{"version":3,"file":"create-openapi-client.d.ts","sourceRoot":"","sources":["../../src/client/create-openapi-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAGN,KAAK,UAAU,EAGf,MAAM,cAAc,CAAC;AAItB,OAAO,KAAK,EACX,WAAW,EACX,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,QAAQ,EAIR,MAAM,SAAS,CAAC;AA6DjB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAClC,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,EAChC,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,EAEtB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,EAC/B,OAAO,EAAE,cAAc,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAA;CAAE,GAClD,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AACrC,wBAAgB,mBAAmB,CAClC,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,EAChC,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,EACtB,OAAO,SAAS,OAAO,GAAG,IAAI,EAE9B,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,EAC/B,GAAG,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,GAC9B,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC"}
|
package/dist/client/types.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ export interface OpenApiOptions {
|
|
|
89
89
|
/**
|
|
90
90
|
* Checks with the spec's schemas, throwing a `ValidationError`: the
|
|
91
91
|
* request before it is sent, the reply before it is returned. `true` is
|
|
92
|
-
* both. Default:
|
|
92
|
+
* both. Default: both, as a plain call of the client checks its reply.
|
|
93
93
|
*/
|
|
94
94
|
validate?: boolean | {
|
|
95
95
|
readonly request?: boolean;
|
|
@@ -97,16 +97,17 @@ export interface OpenApiOptions {
|
|
|
97
97
|
};
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
|
-
* The binding's options, and `decode`, which returns each
|
|
101
|
-
* outputs it: with `dates: 'date'`, a date-time as a
|
|
100
|
+
* The binding's options, and `decode`, on by default, which returns each
|
|
101
|
+
* reply as its schema outputs it: with `dates: 'date'`, a date-time as a
|
|
102
|
+
* `Date`. `decode: false` returns it as JSON carries it, and changes the
|
|
102
103
|
* replies' types: a client whose types are given says so in its third type
|
|
103
|
-
* argument, `createOpenApiClient<ClientOperations, OperationsByRoute,
|
|
104
|
-
* which in turn requires `decode:
|
|
104
|
+
* argument, `createOpenApiClient<ClientOperations, OperationsByRoute, false>`,
|
|
105
|
+
* which in turn requires `decode: false`. Decoding validates the reply.
|
|
105
106
|
*/
|
|
106
|
-
export type OpenApiArgs<Decoded extends boolean> = Decoded extends
|
|
107
|
-
readonly decode:
|
|
107
|
+
export type OpenApiArgs<Decoded extends boolean> = Decoded extends false ? [options: OpenApiOptions & {
|
|
108
|
+
readonly decode: false;
|
|
108
109
|
}] : [options?: OpenApiOptions & {
|
|
109
|
-
readonly decode?:
|
|
110
|
+
readonly decode?: true;
|
|
110
111
|
}];
|
|
111
112
|
/** What a call takes after its input: the core client's call options. */
|
|
112
113
|
export type OperationInit = Omit<CallOptions, 'operationId'>;
|
|
@@ -146,7 +147,7 @@ export type OperationStreamOf<Ops extends OperationsShape<Ops>, K extends keyof
|
|
|
146
147
|
};
|
|
147
148
|
} ? Kind extends 'sse' ? EventStream<Decoded extends true ? Item : Wire> : Stream<Decoded extends true ? Item : Wire> : never;
|
|
148
149
|
/** A bound client whose calls end together. */
|
|
149
|
-
export type OpenApiGroup<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>, Decoded extends boolean =
|
|
150
|
+
export type OpenApiGroup<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>, Decoded extends boolean = true> = OpenApiClient<Ops, Routes, Decoded> & {
|
|
150
151
|
/**
|
|
151
152
|
* Aborts every call and stream of the group still running, with `reason`,
|
|
152
153
|
* or an `AbortError`. The group goes on: the calls made after it run.
|
|
@@ -161,7 +162,7 @@ export type PathsOf<Routes, M extends Method> = keyof Routes extends infer Route
|
|
|
161
162
|
export type MethodsOf<Routes> = keyof Routes extends infer Route ? Route extends `${infer M extends Method} ${string}` ? M : never : never;
|
|
162
163
|
/** The `operationId` of the operation at `M P`. */
|
|
163
164
|
export type IdOf<Ops, Routes, M extends Method, P extends string> = Routes[`${M} ${P}` & keyof Routes] & keyof Ops;
|
|
164
|
-
export type OpenApiClient<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>, Decoded extends boolean =
|
|
165
|
+
export type OpenApiClient<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>, Decoded extends boolean = true> = {
|
|
165
166
|
/** Calls an operation by its `operationId`. */
|
|
166
167
|
op<K extends keyof Ops & string>(id: K, ...args: Args<Ops, K>): Promise<WithResponse<OperationReply<Ops, K, Decoded>>>;
|
|
167
168
|
/**
|
|
@@ -188,7 +189,7 @@ export type OpenApiClient<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Op
|
|
|
188
189
|
* a package that offers them on an object of its own, as
|
|
189
190
|
* `@nxgt/datasource-rest` does.
|
|
190
191
|
*/
|
|
191
|
-
export type PathMethods<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>, Decoded extends boolean =
|
|
192
|
+
export type PathMethods<Ops extends OperationsShape<Ops>, Routes = RoutesOf<Ops>, Decoded extends boolean = true> = {
|
|
192
193
|
readonly [M in MethodsOf<Routes>]: <P extends PathsOf<Routes, M>>(path: P, ...args: Args<Ops, IdOf<Ops, Routes, M, P>>) => Promise<WithResponse<OperationReply<Ops, IdOf<Ops, Routes, M, P>, Decoded>>>;
|
|
193
194
|
};
|
|
194
195
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EACX,WAAW,EACX,WAAW,EACX,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,MAAM,EACN,YAAY,EACZ,MAAM,cAAc,CAAC;AAEtB,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;CAClC;AAED,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IAC/B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB;AAED,oEAAoE;AACpE,MAAM,MAAM,eAAe,CAAC,GAAG,IAAI;KAAG,CAAC,IAAI,MAAM,GAAG,GAAG,eAAe;CAAE,CAAC;AAEzE,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAA;KAAE,CAAC;IACxE,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAED,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,iFAAiF;IACjF,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE;QACf,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,OAAO,EAAE;YAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAAA;SAAE,CAAC;KACjE,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE;QACnB,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG;YAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAAA;SAAE,CAAC;KAC1E,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,CAAC,GAAG,IAAI;IACjC,QAAQ,EAAE,CAAC,IAAI,MAAM,GAAG,GAAG,gBAAgB,GAAG;QAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;KAC5B;CACD,CAAC;AAEF,uGAAuG;AACvG,MAAM,MAAM,QAAQ,CAAC,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,IAAI;KACvD,CAAC,IAAI,MAAM,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;CAC9D,CAAC;AAEF,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EACN,OAAO,GACP;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC/D;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EACX,WAAW,EACX,WAAW,EACX,MAAM,EACN,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,MAAM,EACN,YAAY,EACZ,MAAM,cAAc,CAAC;AAEtB,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;CAClC;AAED,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;IAC/B,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB;AAED,oEAAoE;AACpE,MAAM,MAAM,eAAe,CAAC,GAAG,IAAI;KAAG,CAAC,IAAI,MAAM,GAAG,GAAG,eAAe;CAAE,CAAC;AAEzE,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAA;KAAE,CAAC;IACxE,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAED,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,iFAAiF;IACjF,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE;QACf,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,OAAO,EAAE;YAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAAA;SAAE,CAAC;KACjE,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE;QACnB,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG;YAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAAA;SAAE,CAAC;KAC1E,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,MAAM,cAAc,CAAC,GAAG,IAAI;IACjC,QAAQ,EAAE,CAAC,IAAI,MAAM,GAAG,GAAG,gBAAgB,GAAG;QAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;KAC5B;CACD,CAAC;AAEF,uGAAuG;AACvG,MAAM,MAAM,QAAQ,CAAC,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,IAAI;KACvD,CAAC,IAAI,MAAM,GAAG,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC;CAC9D,CAAC;AAEF,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,EACN,OAAO,GACP;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAC/D;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,CAAC,OAAO,SAAS,OAAO,IAAI,OAAO,SAAS,KAAK,GACrE,CAAC,OAAO,EAAE,cAAc,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAA;CAAE,CAAC,GACtD,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC;AAE3D,yEAAyE;AACzE,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;AAE7D,8DAA8D;AAC9D,MAAM,MAAM,IAAI,CAAC,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,IAAI;IACzE,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa;CACpB,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,cAAc,CACzB,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,EAChC,CAAC,SAAS,MAAM,GAAG,EACnB,OAAO,SAAS,OAAO,IACpB,OAAO,SAAS,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,gFAAgF;AAChF,MAAM,MAAM,SAAS,CAAC,GAAG,IAAI;KAC3B,CAAC,IAAI,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS;QAAE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAA;KAAE,GAClE,CAAC,GACD,KAAK;CACR,CAAC,MAAM,GAAG,CAAC,GACX,MAAM,CAAC;AAER,4FAA4F;AAC5F,MAAM,WAAW,UAAW,SAAQ,aAAa;IAChD;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;IACvC,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC9C;AAED,oDAAoD;AACpD,MAAM,MAAM,UAAU,CACrB,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,EAChC,CAAC,SAAS,MAAM,GAAG,IAChB,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,UAAU,CAAC,CAAC;AAE3C,uGAAuG;AACvG,MAAM,MAAM,iBAAiB,CAC5B,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,EAChC,CAAC,SAAS,MAAM,GAAG,EACnB,OAAO,SAAS,OAAO,IACpB,GAAG,CAAC,CAAC,CAAC,SAAS;IAClB,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;QAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;KAC1B,CAAC;CACF,GACE,IAAI,SAAS,KAAK,GACjB,WAAW,CAAC,OAAO,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAC/C,MAAM,CAAC,OAAO,SAAS,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC,GAC3C,KAAK,CAAC;AAET,+CAA+C;AAC/C,MAAM,MAAM,YAAY,CACvB,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,EAChC,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,EACtB,OAAO,SAAS,OAAO,GAAG,IAAI,IAC3B,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG;IACzC;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC7B,CAAC;AAEF,4FAA4F;AAC5F,MAAM,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,SAAS,MAAM,IAAI,MAAM,MAAM,SAAS,MAAM,KAAK,GAC7E,KAAK,SAAS,GAAG,CAAC,IAAI,MAAM,IAAI,EAAE,GACjC,IAAI,GACJ,KAAK,GACN,KAAK,CAAC;AAET,gFAAgF;AAChF,MAAM,MAAM,SAAS,CAAC,MAAM,IAAI,MAAM,MAAM,SAAS,MAAM,KAAK,GAC7D,KAAK,SAAS,GAAG,MAAM,CAAC,SAAS,MAAM,IAAI,MAAM,EAAE,GAClD,CAAC,GACD,KAAK,GACN,KAAK,CAAC;AAET,mDAAmD;AACnD,MAAM,MAAM,IAAI,CACf,GAAG,EACH,MAAM,EACN,CAAC,SAAS,MAAM,EAChB,CAAC,SAAS,MAAM,IACb,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC;AAEnD,MAAM,MAAM,aAAa,CACxB,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,EAChC,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,EACtB,OAAO,SAAS,OAAO,GAAG,IAAI,IAC3B;IACH,+CAA+C;IAC/C,EAAE,CAAC,CAAC,SAAS,MAAM,GAAG,GAAG,MAAM,EAC9B,EAAE,EAAE,CAAC,EACL,GAAG,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,GACnB,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1D;;;;OAIG;IACH,MAAM,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,CAAC,EAC9B,EAAE,EAAE,CAAC,EACL,GAAG,IAAI,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,GACzB,iBAAiB,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IACtC;;;OAGG;IACH,KAAK,IAAI,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;CACzC,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtC;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CACtB,GAAG,SAAS,eAAe,CAAC,GAAG,CAAC,EAChC,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,EACtB,OAAO,SAAS,OAAO,GAAG,IAAI,IAC3B;IACH,QAAQ,EAAE,CAAC,IAAI,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,EAC/D,IAAI,EAAE,CAAC,EACP,GAAG,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,KACvC,OAAO,CACX,YAAY,CAAC,cAAc,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CACnE;CACD,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/client/create-openapi-client.ts
|
|
2
2
|
import {
|
|
3
|
+
ClientError,
|
|
3
4
|
ValidationError
|
|
4
5
|
} from "@nxgt/httpyz";
|
|
5
6
|
import { METHODS } from "@nxgt/httpyz/integration";
|
|
@@ -172,8 +173,8 @@ function createOpenApiClient(http, operations, given) {
|
|
|
172
173
|
}
|
|
173
174
|
var joined = (given, scope) => scope === undefined ? given : given ? AbortSignal.any([given, scope]) : scope;
|
|
174
175
|
function bind(http, operations, options, scope) {
|
|
175
|
-
const { validate =
|
|
176
|
-
const decode = options.decode
|
|
176
|
+
const { validate = true } = options;
|
|
177
|
+
const decode = options.decode !== false;
|
|
177
178
|
const checks = {
|
|
178
179
|
request: validate === true || typeof validate === "object" && validate.request === true,
|
|
179
180
|
response: decode || validate === true || typeof validate === "object" && validate.response === true
|
|
@@ -277,11 +278,14 @@ function bind(http, operations, options, scope) {
|
|
|
277
278
|
});
|
|
278
279
|
}
|
|
279
280
|
};
|
|
281
|
+
const methods = new Set(Object.values(table).map(({ method }) => method));
|
|
280
282
|
for (const method of METHODS) {
|
|
283
|
+
if (!methods.has(method))
|
|
284
|
+
continue;
|
|
281
285
|
client[method] = (path, ...args) => {
|
|
282
286
|
const id = byRoute.get(`${method} ${path}`);
|
|
283
287
|
if (id === undefined) {
|
|
284
|
-
return Promise.reject(new
|
|
288
|
+
return Promise.reject(new ClientError({ method, path }, "the spec has no operation at it"));
|
|
285
289
|
}
|
|
286
290
|
return call(id, args);
|
|
287
291
|
};
|
|
@@ -292,5 +296,5 @@ export {
|
|
|
292
296
|
createOpenApiClient
|
|
293
297
|
};
|
|
294
298
|
|
|
295
|
-
//# debugId=
|
|
299
|
+
//# debugId=01C92EAE9D90053664756E2164756E21
|
|
296
300
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/client/create-openapi-client.ts", "../src/request/check-request.ts", "../src/request/to-request.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * `createOpenApiClient`: the operations `@nxgt/openapi-codegen` generates,\n * bound onto a client of `createHttpClient`. The client sends; the binding\n * adds what the spec knows: how each parameter and body is written, the\n * replies each operation declares, and checks by the server's own schemas.\n */\nimport {\n\ttype EventStream,\n\ttype HttpClient,\n\ttype Responses,\n\tValidationError,\n} from '@nxgt/httpyz';\nimport { METHODS } from '@nxgt/httpyz/integration';\nimport { checkRequest } from '../request/check-request';\nimport { type Input, toRequest } from '../request/to-request';\nimport type {\n\tOpenApiArgs,\n\tOpenApiClient,\n\tOpenApiOptions,\n\tOperationsShape,\n\tOperationTable,\n\tRoutesOf,\n\tRuntimeMedia,\n\tRuntimeOperation,\n\tStreamInit,\n} from './types';\n\n/** An operation's replies as the core client declares them. */\nconst toResponses = (operation: RuntimeOperation): Responses =>\n\tObject.fromEntries(\n\t\tObject.entries(operation.responses).map(([status, content]) => [\n\t\t\tstatus,\n\t\t\tObject.keys(content).length === 0\n\t\t\t\t? null\n\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\tObject.entries(content).map(([type, media]) => [\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\tmedia.schema ?? null,\n\t\t\t\t\t\t]),\n\t\t\t\t\t),\n\t\t]),\n\t);\n\n/** The stream an operation replies with, and its media type: the first of its 2xx replies. */\nfunction streamOf(\n\toperation: RuntimeOperation,\n): [type: string, media: RuntimeMedia] | undefined {\n\tfor (const [status, content] of Object.entries(operation.responses)) {\n\t\tconst code = Number(status);\n\t\tif (code < 200 || code > 299) continue;\n\t\tfor (const [type, media] of Object.entries(content)) {\n\t\t\tif (media.kind === 'sse' || media.kind === 'jsonl') return [type, media];\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * `open()`'s stream, opened once `check` passes on the first read: a request\n * the spec refuses is never sent, and throws where the stream is read.\n */\nfunction checkedFirst<T>(\n\topen: () => EventStream<T>,\n\tcheck: () => Promise<void>,\n): EventStream<T> {\n\tlet inner: EventStream<T> | undefined;\n\tlet closed = false;\n\treturn {\n\t\tget lastEventId() {\n\t\t\treturn inner?.lastEventId;\n\t\t},\n\t\tclose() {\n\t\t\tclosed = true;\n\t\t\tinner?.close();\n\t\t},\n\t\tasync *[Symbol.asyncIterator]() {\n\t\t\tif (!inner) {\n\t\t\t\tawait check();\n\t\t\t\tif (closed) return;\n\t\t\t\tinner = open();\n\t\t\t}\n\t\t\tyield* inner;\n\t\t},\n\t};\n}\n\n/**\n * A client for a spec, bound to the `operations` table of the generated\n * `operations.ts`, which carries the spec's types: nothing else to import.\n *\n * ```ts\n * const http = createHttpClient({ baseUrl: 'https://api.example.com' });\n * const api = createOpenApiClient(http, operations);\n * const reply = await api.get('/employees/{id}', { param: { id } });\n * if (reply.status === 200) reply.data.name;\n * ```\n *\n * With `decode: true`, each reply is returned as its schema outputs it, and\n * typed so. The types may also be given: `createOpenApiClient<ClientOperations,\n * OperationsByRoute, true>`, whose `true` then requires `decode: true`.\n */\nexport function createOpenApiClient<\n\tOps extends OperationsShape<Ops>,\n\tRoutes = RoutesOf<Ops>,\n>(\n\thttp: HttpClient,\n\toperations: OperationTable<Ops>,\n\toptions: OpenApiOptions & { readonly decode: true },\n): OpenApiClient<Ops, Routes, true>;\nexport function createOpenApiClient<\n\tOps extends OperationsShape<Ops>,\n\tRoutes = RoutesOf<Ops>,\n\tDecoded extends boolean = false,\n>(\n\thttp: HttpClient,\n\toperations: OperationTable<Ops>,\n\t...[given]: OpenApiArgs<Decoded>\n): OpenApiClient<Ops, Routes, Decoded>;\nexport function createOpenApiClient<\n\tOps extends OperationsShape<Ops>,\n\tRoutes,\n\tDecoded extends boolean,\n>(\n\thttp: HttpClient,\n\toperations: OperationTable<Ops>,\n\tgiven?: OpenApiOptions & { readonly decode?: boolean },\n): OpenApiClient<Ops, Routes, Decoded> {\n\treturn bind(http, operations, given ?? {}, () => undefined);\n}\n\n/** Both signals: a call ends on either. */\nconst joined = (\n\tgiven: AbortSignal | null | undefined,\n\tscope: AbortSignal | undefined,\n): AbortSignal | null | undefined =>\n\tscope === undefined ? given : given ? AbortSignal.any([given, scope]) : scope;\n\n/**\n * The client, whose calls also end on `scope()`'s signal, read as each call\n * is made: a call checked before it is sent reaches the core client later,\n * after a `cancel()` of its group may already have swapped the signal.\n */\nfunction bind<\n\tOps extends OperationsShape<Ops>,\n\tRoutes,\n\tDecoded extends boolean,\n>(\n\thttp: HttpClient,\n\toperations: OperationTable<Ops>,\n\toptions: OpenApiOptions & { readonly decode?: boolean },\n\tscope: () => AbortSignal | undefined,\n): OpenApiClient<Ops, Routes, Decoded> {\n\tconst { validate = false } = options;\n\tconst decode = options.decode === true;\n\tconst checks = {\n\t\trequest:\n\t\t\tvalidate === true ||\n\t\t\t(typeof validate === 'object' && validate.request === true),\n\t\tresponse:\n\t\t\tdecode ||\n\t\t\tvalidate === true ||\n\t\t\t(typeof validate === 'object' && validate.response === true),\n\t};\n\tconst table = operations as unknown as {\n\t\treadonly [id: string]: RuntimeOperation;\n\t};\n\tconst byRoute = new Map<string, string>();\n\tconst responses = new Map<string, Responses>();\n\tfor (const [id, operation] of Object.entries(table)) {\n\t\tbyRoute.set(`${operation.method} ${operation.path}`, id);\n\t\tresponses.set(id, toResponses(operation));\n\t}\n\n\t/** The operation, and its arguments: the input, then the init. */\n\tconst read = (id: string, args: readonly unknown[]) => {\n\t\tconst operation = table[id];\n\t\tif (!operation) throw new Error(`${id} is not an operationId of the spec`);\n\t\t// An operation that takes nothing has no input: its first argument is the init.\n\t\tconst takes =\n\t\t\toperation.parameters.length > 0 ||\n\t\t\tObject.keys(operation.body?.content ?? {}).length > 0;\n\t\tconst input = (takes ? args[0] : undefined) as Input | undefined;\n\t\tconst given = ((takes ? args[1] : args[0]) ?? {}) as StreamInit;\n\t\tconst signal = joined(given.signal, scope());\n\t\tconst init = signal ? { ...given, signal } : given;\n\t\treturn { operation, input, init };\n\t};\n\n\t/** Throws what the server would refuse, before anything is sent. */\n\tconst check = async (\n\t\tid: string,\n\t\toperation: RuntimeOperation,\n\t\tinput: Input | undefined,\n\t): Promise<void> => {\n\t\tif (!checks.request) return;\n\t\tconst issues = await checkRequest(operation, input);\n\t\tif (issues.length === 0) return;\n\t\tconst context = {\n\t\t\toperationId: id,\n\t\t\tmethod: operation.method,\n\t\t\tpath: operation.path,\n\t\t};\n\t\tthrow new ValidationError(context, {\n\t\t\tkind: 'request',\n\t\t\t...context,\n\t\t\tissues,\n\t\t});\n\t};\n\n\t/** The core client's options for the input, written as the server reads it. */\n\tconst written = (\n\t\tid: string,\n\t\toperation: RuntimeOperation,\n\t\tinput: Input | undefined,\n\t\tinit: object & { headers?: HeadersInit },\n\t) => {\n\t\tconst headers = new Headers(init.headers);\n\t\tconst { query, body } = toRequest(operation, input, headers);\n\t\treturn {\n\t\t\t...init,\n\t\t\t...body,\n\t\t\tparam: input?.param,\n\t\t\tquery,\n\t\t\theaders,\n\t\t\toperationId: id,\n\t\t};\n\t};\n\n\tconst call = async (\n\t\tid: string,\n\t\targs: readonly unknown[],\n\t): Promise<unknown> => {\n\t\tconst { operation, input, init } = read(id, args);\n\t\tawait check(id, operation, input);\n\t\tconst request = http.request as (\n\t\t\tmethod: string,\n\t\t\tpath: string,\n\t\t\toptions: object,\n\t\t) => Promise<unknown>;\n\t\treturn request(operation.method, operation.path, {\n\t\t\t...written(id, operation, input, init),\n\t\t\tresponses: responses.get(id),\n\t\t\tvalidate: checks.response,\n\t\t\tdecode,\n\t\t});\n\t};\n\n\tconst stream = (id: string, args: readonly unknown[]) => {\n\t\tconst { operation, input, init } = read(id, args);\n\t\tconst found = streamOf(operation);\n\t\tif (!found) throw new Error(`${id} does not reply with a stream`);\n\t\tconst [type, media] = found;\n\t\tconst { reconnect, lastEventId, onUnknownEvent, ...rest } = init;\n\t\tconst open = () => {\n\t\t\tconst request = written(id, operation, input, rest);\n\t\t\t// The media type the spec declares, which may not be the core client's default.\n\t\t\tif (!request.headers.has('accept')) request.headers.set('accept', type);\n\t\t\tconst common = {\n\t\t\t\t...request,\n\t\t\t\tmethod: operation.method,\n\t\t\t\tvalidate: checks.response,\n\t\t\t\tdecode,\n\t\t\t};\n\t\t\tconst openStream = (media.kind === 'sse' ? http.events : http.lines) as (\n\t\t\t\tpath: string,\n\t\t\t\toptions: object,\n\t\t\t) => EventStream<unknown>;\n\t\t\treturn openStream(\n\t\t\t\toperation.path,\n\t\t\t\tmedia.kind === 'sse'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...common,\n\t\t\t\t\t\t\tevents: media.events,\n\t\t\t\t\t\t\treconnect,\n\t\t\t\t\t\t\tlastEventId,\n\t\t\t\t\t\t\tonUnknownEvent,\n\t\t\t\t\t\t}\n\t\t\t\t\t: { ...common, item: media.item },\n\t\t\t);\n\t\t};\n\t\treturn checks.request\n\t\t\t? checkedFirst(open, () => check(id, operation, input))\n\t\t\t: open();\n\t};\n\n\tconst client: Record<string, unknown> = {\n\t\toperations,\n\t\top: (id: string, ...args: unknown[]) => call(id, args),\n\t\tstream: (id: string, ...args: unknown[]) => stream(id, args),\n\t\tgroup: () => {\n\t\t\tconst group = http.group();\n\t\t\tconst bound = bind<Ops, Routes, Decoded>(\n\t\t\t\tgroup,\n\t\t\t\toperations,\n\t\t\t\toptions,\n\t\t\t\t() => group.signal,\n\t\t\t);\n\t\t\treturn Object.defineProperties(bound, {\n\t\t\t\tcancel: { enumerable: true, value: group.cancel },\n\t\t\t\tsignal: { enumerable: true, get: () => group.signal },\n\t\t\t});\n\t\t},\n\t};\n\tfor (const method of METHODS) {\n\t\tclient[method] = (path: string, ...args: unknown[]) => {\n\t\t\tconst id = byRoute.get(`${method} ${path}`);\n\t\t\tif (id === undefined) {\n\t\t\t\treturn Promise.reject(\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t`The spec has no ${method.toUpperCase()} ${path} operation`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn call(id, args);\n\t\t};\n\t}\n\treturn client as unknown as OpenApiClient<Ops, Routes, Decoded>;\n}\n",
|
|
5
|
+
"/**\n * `createOpenApiClient`: the operations `@nxgt/openapi-codegen` generates,\n * bound onto a client of `createHttpClient`. The client sends; the binding\n * adds what the spec knows: how each parameter and body is written, the\n * replies each operation declares, and checks by the server's own schemas.\n */\nimport {\n\tClientError,\n\ttype EventStream,\n\ttype HttpClient,\n\ttype Responses,\n\tValidationError,\n} from '@nxgt/httpyz';\nimport { METHODS } from '@nxgt/httpyz/integration';\nimport { checkRequest } from '../request/check-request';\nimport { type Input, toRequest } from '../request/to-request';\nimport type {\n\tOpenApiArgs,\n\tOpenApiClient,\n\tOpenApiOptions,\n\tOperationsShape,\n\tOperationTable,\n\tRoutesOf,\n\tRuntimeMedia,\n\tRuntimeOperation,\n\tStreamInit,\n} from './types';\n\n/** An operation's replies as the core client declares them. */\nconst toResponses = (operation: RuntimeOperation): Responses =>\n\tObject.fromEntries(\n\t\tObject.entries(operation.responses).map(([status, content]) => [\n\t\t\tstatus,\n\t\t\tObject.keys(content).length === 0\n\t\t\t\t? null\n\t\t\t\t: Object.fromEntries(\n\t\t\t\t\t\tObject.entries(content).map(([type, media]) => [\n\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\tmedia.schema ?? null,\n\t\t\t\t\t\t]),\n\t\t\t\t\t),\n\t\t]),\n\t);\n\n/** The stream an operation replies with, and its media type: the first of its 2xx replies. */\nfunction streamOf(\n\toperation: RuntimeOperation,\n): [type: string, media: RuntimeMedia] | undefined {\n\tfor (const [status, content] of Object.entries(operation.responses)) {\n\t\tconst code = Number(status);\n\t\tif (code < 200 || code > 299) continue;\n\t\tfor (const [type, media] of Object.entries(content)) {\n\t\t\tif (media.kind === 'sse' || media.kind === 'jsonl') return [type, media];\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * `open()`'s stream, opened once `check` passes on the first read: a request\n * the spec refuses is never sent, and throws where the stream is read.\n */\nfunction checkedFirst<T>(\n\topen: () => EventStream<T>,\n\tcheck: () => Promise<void>,\n): EventStream<T> {\n\tlet inner: EventStream<T> | undefined;\n\tlet closed = false;\n\treturn {\n\t\tget lastEventId() {\n\t\t\treturn inner?.lastEventId;\n\t\t},\n\t\tclose() {\n\t\t\tclosed = true;\n\t\t\tinner?.close();\n\t\t},\n\t\tasync *[Symbol.asyncIterator]() {\n\t\t\tif (!inner) {\n\t\t\t\tawait check();\n\t\t\t\tif (closed) return;\n\t\t\t\tinner = open();\n\t\t\t}\n\t\t\tyield* inner;\n\t\t},\n\t};\n}\n\n/**\n * A client for a spec, bound to the `operations` table of the generated\n * `operations.ts`, which carries the spec's types: nothing else to import.\n *\n * ```ts\n * const http = createHttpClient({ baseUrl: 'https://api.example.com' });\n * const api = createOpenApiClient(http, operations);\n * const reply = await api.get('/employees/{id}', { param: { id } });\n * if (reply.status === 200) reply.data.name;\n * ```\n *\n * It checks the request and the reply, and returns each reply as its schema\n * outputs it, typed so. `decode: false` returns it as JSON carries it. The\n * types may also be given: `createOpenApiClient<ClientOperations,\n * OperationsByRoute, false>`, whose `false` then requires `decode: false`.\n */\nexport function createOpenApiClient<\n\tOps extends OperationsShape<Ops>,\n\tRoutes = RoutesOf<Ops>,\n>(\n\thttp: HttpClient,\n\toperations: OperationTable<Ops>,\n\toptions: OpenApiOptions & { readonly decode: false },\n): OpenApiClient<Ops, Routes, false>;\nexport function createOpenApiClient<\n\tOps extends OperationsShape<Ops>,\n\tRoutes = RoutesOf<Ops>,\n\tDecoded extends boolean = true,\n>(\n\thttp: HttpClient,\n\toperations: OperationTable<Ops>,\n\t...[given]: OpenApiArgs<Decoded>\n): OpenApiClient<Ops, Routes, Decoded>;\nexport function createOpenApiClient<\n\tOps extends OperationsShape<Ops>,\n\tRoutes,\n\tDecoded extends boolean,\n>(\n\thttp: HttpClient,\n\toperations: OperationTable<Ops>,\n\tgiven?: OpenApiOptions & { readonly decode?: boolean },\n): OpenApiClient<Ops, Routes, Decoded> {\n\treturn bind(http, operations, given ?? {}, () => undefined);\n}\n\n/** Both signals: a call ends on either. */\nconst joined = (\n\tgiven: AbortSignal | null | undefined,\n\tscope: AbortSignal | undefined,\n): AbortSignal | null | undefined =>\n\tscope === undefined ? given : given ? AbortSignal.any([given, scope]) : scope;\n\n/**\n * The client, whose calls also end on `scope()`'s signal, read as each call\n * is made: a call checked before it is sent reaches the core client later,\n * after a `cancel()` of its group may already have swapped the signal.\n */\nfunction bind<\n\tOps extends OperationsShape<Ops>,\n\tRoutes,\n\tDecoded extends boolean,\n>(\n\thttp: HttpClient,\n\toperations: OperationTable<Ops>,\n\toptions: OpenApiOptions & { readonly decode?: boolean },\n\tscope: () => AbortSignal | undefined,\n): OpenApiClient<Ops, Routes, Decoded> {\n\tconst { validate = true } = options;\n\tconst decode = options.decode !== false;\n\tconst checks = {\n\t\trequest:\n\t\t\tvalidate === true ||\n\t\t\t(typeof validate === 'object' && validate.request === true),\n\t\tresponse:\n\t\t\tdecode ||\n\t\t\tvalidate === true ||\n\t\t\t(typeof validate === 'object' && validate.response === true),\n\t};\n\tconst table = operations as unknown as {\n\t\treadonly [id: string]: RuntimeOperation;\n\t};\n\tconst byRoute = new Map<string, string>();\n\tconst responses = new Map<string, Responses>();\n\tfor (const [id, operation] of Object.entries(table)) {\n\t\tbyRoute.set(`${operation.method} ${operation.path}`, id);\n\t\tresponses.set(id, toResponses(operation));\n\t}\n\n\t/** The operation, and its arguments: the input, then the init. */\n\tconst read = (id: string, args: readonly unknown[]) => {\n\t\tconst operation = table[id];\n\t\tif (!operation) throw new Error(`${id} is not an operationId of the spec`);\n\t\t// An operation that takes nothing has no input: its first argument is the init.\n\t\tconst takes =\n\t\t\toperation.parameters.length > 0 ||\n\t\t\tObject.keys(operation.body?.content ?? {}).length > 0;\n\t\tconst input = (takes ? args[0] : undefined) as Input | undefined;\n\t\tconst given = ((takes ? args[1] : args[0]) ?? {}) as StreamInit;\n\t\tconst signal = joined(given.signal, scope());\n\t\tconst init = signal ? { ...given, signal } : given;\n\t\treturn { operation, input, init };\n\t};\n\n\t/** Throws what the server would refuse, before anything is sent. */\n\tconst check = async (\n\t\tid: string,\n\t\toperation: RuntimeOperation,\n\t\tinput: Input | undefined,\n\t): Promise<void> => {\n\t\tif (!checks.request) return;\n\t\tconst issues = await checkRequest(operation, input);\n\t\tif (issues.length === 0) return;\n\t\tconst context = {\n\t\t\toperationId: id,\n\t\t\tmethod: operation.method,\n\t\t\tpath: operation.path,\n\t\t};\n\t\tthrow new ValidationError(context, {\n\t\t\tkind: 'request',\n\t\t\t...context,\n\t\t\tissues,\n\t\t});\n\t};\n\n\t/** The core client's options for the input, written as the server reads it. */\n\tconst written = (\n\t\tid: string,\n\t\toperation: RuntimeOperation,\n\t\tinput: Input | undefined,\n\t\tinit: object & { headers?: HeadersInit },\n\t) => {\n\t\tconst headers = new Headers(init.headers);\n\t\tconst { query, body } = toRequest(operation, input, headers);\n\t\treturn {\n\t\t\t...init,\n\t\t\t...body,\n\t\t\tparam: input?.param,\n\t\t\tquery,\n\t\t\theaders,\n\t\t\toperationId: id,\n\t\t};\n\t};\n\n\tconst call = async (\n\t\tid: string,\n\t\targs: readonly unknown[],\n\t): Promise<unknown> => {\n\t\tconst { operation, input, init } = read(id, args);\n\t\tawait check(id, operation, input);\n\t\tconst request = http.request as (\n\t\t\tmethod: string,\n\t\t\tpath: string,\n\t\t\toptions: object,\n\t\t) => Promise<unknown>;\n\t\treturn request(operation.method, operation.path, {\n\t\t\t...written(id, operation, input, init),\n\t\t\tresponses: responses.get(id),\n\t\t\tvalidate: checks.response,\n\t\t\tdecode,\n\t\t});\n\t};\n\n\tconst stream = (id: string, args: readonly unknown[]) => {\n\t\tconst { operation, input, init } = read(id, args);\n\t\tconst found = streamOf(operation);\n\t\tif (!found) throw new Error(`${id} does not reply with a stream`);\n\t\tconst [type, media] = found;\n\t\tconst { reconnect, lastEventId, onUnknownEvent, ...rest } = init;\n\t\tconst open = () => {\n\t\t\tconst request = written(id, operation, input, rest);\n\t\t\t// The media type the spec declares, which may not be the core client's default.\n\t\t\tif (!request.headers.has('accept')) request.headers.set('accept', type);\n\t\t\tconst common = {\n\t\t\t\t...request,\n\t\t\t\tmethod: operation.method,\n\t\t\t\tvalidate: checks.response,\n\t\t\t\tdecode,\n\t\t\t};\n\t\t\tconst openStream = (media.kind === 'sse' ? http.events : http.lines) as (\n\t\t\t\tpath: string,\n\t\t\t\toptions: object,\n\t\t\t) => EventStream<unknown>;\n\t\t\treturn openStream(\n\t\t\t\toperation.path,\n\t\t\t\tmedia.kind === 'sse'\n\t\t\t\t\t? {\n\t\t\t\t\t\t\t...common,\n\t\t\t\t\t\t\tevents: media.events,\n\t\t\t\t\t\t\treconnect,\n\t\t\t\t\t\t\tlastEventId,\n\t\t\t\t\t\t\tonUnknownEvent,\n\t\t\t\t\t\t}\n\t\t\t\t\t: { ...common, item: media.item },\n\t\t\t);\n\t\t};\n\t\treturn checks.request\n\t\t\t? checkedFirst(open, () => check(id, operation, input))\n\t\t\t: open();\n\t};\n\n\tconst client: Record<string, unknown> = {\n\t\toperations,\n\t\top: (id: string, ...args: unknown[]) => call(id, args),\n\t\tstream: (id: string, ...args: unknown[]) => stream(id, args),\n\t\tgroup: () => {\n\t\t\tconst group = http.group();\n\t\t\tconst bound = bind<Ops, Routes, Decoded>(\n\t\t\t\tgroup,\n\t\t\t\toperations,\n\t\t\t\toptions,\n\t\t\t\t() => group.signal,\n\t\t\t);\n\t\t\treturn Object.defineProperties(bound, {\n\t\t\t\tcancel: { enumerable: true, value: group.cancel },\n\t\t\t\tsignal: { enumerable: true, get: () => group.signal },\n\t\t\t});\n\t\t},\n\t};\n\t// Only the spec's methods, as the types have them: no `trace` without a TRACE operation.\n\tconst methods = new Set(Object.values(table).map(({ method }) => method));\n\tfor (const method of METHODS) {\n\t\tif (!methods.has(method)) continue;\n\t\tclient[method] = (path: string, ...args: unknown[]) => {\n\t\t\tconst id = byRoute.get(`${method} ${path}`);\n\t\t\tif (id === undefined) {\n\t\t\t\treturn Promise.reject(\n\t\t\t\t\tnew ClientError({ method, path }, 'the spec has no operation at it'),\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn call(id, args);\n\t\t};\n\t}\n\treturn client as unknown as OpenApiClient<Ops, Routes, Decoded>;\n}\n",
|
|
6
6
|
"/**\n * A request checked before it is sent, by the validators the server runs, on\n * what `@nxgt/openapi-hono` will read from it: each parameter as the\n * text it travels as, the JSON as it parses, a form as its fields. What the\n * server would refuse is refused here with the same issues, and nothing is\n * sent.\n */\nimport type { StandardSchemaV1, ValidationIssue } from '@nxgt/httpyz';\nimport { absent, check, fields, text } from '@nxgt/httpyz/integration';\nimport type { RuntimeMedia, RuntimeOperation } from '../client/types';\nimport type { Input } from './to-request';\n\nexport async function checkRequest(\n\toperation: RuntimeOperation,\n\tinput: Input | undefined,\n): Promise<ValidationIssue[]> {\n\tconst issues: ValidationIssue[] = [];\n\tconst run = async (\n\t\ttarget: ValidationIssue['target'],\n\t\tschema: StandardSchemaV1 | undefined,\n\t\tvalue: unknown,\n\t): Promise<void> => {\n\t\tif (!schema) return;\n\t\tconst result = await check(schema, value, target);\n\t\tif (!result.ok) issues.push(...result.issues);\n\t};\n\tconst { param, query, header } = readParameters(operation, input);\n\t// In the server's order, so the issues come out in the same one.\n\tawait run('param', operation.param, param);\n\tawait run('query', operation.query, query);\n\tawait run('header', operation.header, header);\n\tconst content = Object.values(operation.body?.content ?? {});\n\tconst schemaOf = (kind: RuntimeMedia['kind']) =>\n\t\tcontent.find((media) => media.kind === kind)?.schema;\n\tif (input?.json !== undefined) {\n\t\tconst sent = JSON.stringify(input.json);\n\t\tawait run(\n\t\t\t'json',\n\t\t\tschemaOf('json'),\n\t\t\tsent === undefined ? undefined : JSON.parse(sent),\n\t\t);\n\t} else if (input?.form !== undefined) {\n\t\tawait run('form', schemaOf('form'), formFields(input.form));\n\t} else if (input?.text !== undefined) {\n\t\tawait run('body', schemaOf('text'), input.text);\n\t}\n\treturn issues;\n}\n\n/** The parameters as the engine reads them: strings, a list as every value. */\nfunction readParameters(\n\toperation: RuntimeOperation,\n\tinput: Input | undefined,\n): Record<'param' | 'query' | 'header', Record<string, unknown>> {\n\tconst read = { param: {}, query: {}, header: {} } as Record<\n\t\t'param' | 'query' | 'header',\n\t\tRecord<string, unknown>\n\t>;\n\tfor (const parameter of operation.parameters) {\n\t\tconst { name, list } = parameter;\n\t\tif (parameter.in === 'path') {\n\t\t\tconst value = input?.param?.[name];\n\t\t\tif (!absent(value)) read.param[name] = text(value);\n\t\t\tcontinue;\n\t\t}\n\t\tconst value =\n\t\t\tparameter.in === 'query'\n\t\t\t\t? input?.query?.[name]\n\t\t\t\t: input?.header?.[name.toLowerCase()];\n\t\tif (absent(value)) continue;\n\t\tconst values = Array.isArray(value) ? value.map(text) : [text(value)];\n\t\tif (parameter.in === 'header') {\n\t\t\t// Headers trims what it holds.\n\t\t\tconst sent = values.join(',').trim();\n\t\t\tread.header[name.toLowerCase()] = list\n\t\t\t\t? sent.split(',').map((item) => item.trim())\n\t\t\t\t: sent;\n\t\t} else if (list) {\n\t\t\tread.query[name] = parameter.explode\n\t\t\t\t? values\n\t\t\t\t: values.join(',').split(',');\n\t\t} else read.query[name] = values.join(',');\n\t}\n\treturn read;\n}\n\n/**\n * A form as Hono's `parseBody({ all: true })` reads it: a field sent once is\n * its value, one sent again or named `x[]` a list, and a `Blob` a `File`.\n */\nfunction formFields(\n\tform: Readonly<Record<string, unknown>>,\n): Record<string, unknown> {\n\tconst read: Record<string, unknown> = {};\n\tfor (const [name, value] of fields(form)) {\n\t\tconst item =\n\t\t\tvalue instanceof Blob && !(value instanceof File)\n\t\t\t\t? new File([value], 'blob', { type: value.type })\n\t\t\t\t: value;\n\t\tconst held = read[name];\n\t\tread[name] =\n\t\t\theld === undefined\n\t\t\t\t? name.endsWith('[]')\n\t\t\t\t\t? [item]\n\t\t\t\t\t: item\n\t\t\t\t: Array.isArray(held)\n\t\t\t\t\t? [...held, item]\n\t\t\t\t\t: [held, item];\n\t}\n\treturn read;\n}\n",
|
|
7
7
|
"/**\n * An operation's input as a call of the core client, written the way\n * `@nxgt/openapi-hono` reads it back: a query list as a repeated key,\n * or joined with commas when the spec says `explode: false`; a header list\n * joined with commas; the body as the media type the spec declares for its\n * kind.\n */\nimport type { BodyInput } from '@nxgt/httpyz';\nimport {\n\tabsent,\n\ttext,\n\ttoFormData,\n\ttoSearchParams,\n} from '@nxgt/httpyz/integration';\nimport type {\n\tRuntimeMedia,\n\tRuntimeOperation,\n\tRuntimeParameter,\n} from '../client/types';\n\n/** What an input may hold, as `ClientOperations` types it. */\nexport interface Input {\n\treadonly param?: Readonly<Record<string, unknown>>;\n\treadonly query?: Readonly<Record<string, unknown>>;\n\t/** Keyed by lowercased name. */\n\treadonly header?: Readonly<Record<string, unknown>>;\n\treadonly json?: unknown;\n\treadonly form?: Readonly<Record<string, unknown>>;\n\treadonly text?: string;\n\treadonly body?: Blob | ArrayBuffer | Uint8Array;\n}\n\n/** What to send as `Content-Type` for a declared media type, which may be a range. */\nconst concrete = (type: string | undefined, fallback: string): string =>\n\ttype === undefined || type.includes('*') ? fallback : type;\n\n/** The query and the body; the header parameters and the body's type go onto `headers`. */\nexport function toRequest(\n\toperation: RuntimeOperation,\n\tinput: Input | undefined,\n\theaders: Headers,\n): { query: URLSearchParams; body: BodyInput } {\n\tconst query = new URLSearchParams();\n\tfor (const param of operation.parameters) {\n\t\tif (param.in === 'query') {\n\t\t\tappendQuery(query, param, input?.query?.[param.name]);\n\t\t} else if (param.in === 'header') {\n\t\t\tconst value = input?.header?.[param.name.toLowerCase()];\n\t\t\tif (absent(value)) continue;\n\t\t\theaders.set(\n\t\t\t\tparam.name,\n\t\t\t\tArray.isArray(value) ? value.map(text).join(',') : text(value),\n\t\t\t);\n\t\t}\n\t}\n\treturn { query, body: toBody(operation, input, headers) };\n}\n\nfunction appendQuery(\n\tsearch: URLSearchParams,\n\tparam: RuntimeParameter,\n\tvalue: unknown,\n): void {\n\tif (absent(value)) return;\n\tif (!Array.isArray(value)) search.append(param.name, text(value));\n\telse if (param.explode) {\n\t\tfor (const item of value) search.append(param.name, text(item));\n\t} else search.append(param.name, value.map(text).join(','));\n}\n\nfunction toBody(\n\toperation: RuntimeOperation,\n\tinput: Input | undefined,\n\theaders: Headers,\n): BodyInput {\n\tif (input === undefined) return {};\n\tconst content = Object.entries(operation.body?.content ?? {});\n\tconst declared = (kind: RuntimeMedia['kind']): string | undefined =>\n\t\tcontent.find(([, media]) => media.kind === kind)?.[0];\n\tif (input.json !== undefined) {\n\t\theaders.set('content-type', concrete(declared('json'), 'application/json'));\n\t\treturn { json: input.json };\n\t}\n\tif (input.form !== undefined) {\n\t\treturn {\n\t\t\tform:\n\t\t\t\tdeclared('form') === 'application/x-www-form-urlencoded'\n\t\t\t\t\t? toSearchParams(input.form)\n\t\t\t\t\t: toFormData(input.form),\n\t\t};\n\t}\n\tif (input.text !== undefined) {\n\t\theaders.set('content-type', concrete(declared('text'), 'text/plain'));\n\t\treturn { text: input.text };\n\t}\n\tif (input.body !== undefined) {\n\t\theaders.set(\n\t\t\t'content-type',\n\t\t\tconcrete(declared('binary'), 'application/octet-stream'),\n\t\t);\n\t\treturn { body: input.body };\n\t}\n\treturn {};\n}\n"
|
|
8
8
|
],
|
|
9
|
-
"mappings": ";AAMA;AAAA;AAAA;
|
|
10
|
-
"debugId": "
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "01C92EAE9D90053664756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/openapi-httpyz",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"license": "
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"files": [
|
|
9
9
|
"dist",
|
|
10
10
|
"README.md",
|
|
11
|
-
"package.json"
|
|
11
|
+
"package.json",
|
|
12
|
+
"LICENSE"
|
|
12
13
|
],
|
|
13
14
|
"exports": {
|
|
14
15
|
".": {
|
|
@@ -34,15 +35,15 @@
|
|
|
34
35
|
"typecheck": "bun run fixtures && tsc --noEmit"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
|
-
"@nxgt/httpyz": "^0.
|
|
38
|
-
"@nxgt/openapi-codegen": "^0.
|
|
39
|
-
"@nxgt/openapi-hono": "^0.
|
|
38
|
+
"@nxgt/httpyz": "^0.1.0",
|
|
39
|
+
"@nxgt/openapi-codegen": "^0.2.0",
|
|
40
|
+
"@nxgt/openapi-hono": "^0.1.0",
|
|
40
41
|
"@types/bun": "^1.4.0",
|
|
41
42
|
"hono": "^4.13.4",
|
|
42
43
|
"zod": "^4.5.4"
|
|
43
44
|
},
|
|
44
45
|
"peerDependencies": {
|
|
45
|
-
"@nxgt/httpyz": "^0.
|
|
46
|
+
"@nxgt/httpyz": "^0.1.0",
|
|
46
47
|
"typescript": "^6.0.3"
|
|
47
48
|
}
|
|
48
49
|
}
|