@monarcode/effetch 0.1.0-alpha.1 → 0.1.0-alpha.2
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 +23 -0
- package/README.md +22 -17
- package/dist/Client.d.ts +12 -12
- package/dist/Client.js +1 -1
- package/dist/Errors.d.ts +4 -3
- package/dist/Errors.js +4 -3
- package/dist/Options.d.ts +56 -18
- package/dist/index.d.ts +2 -0
- package/dist/internal/body.js +1 -1
- package/dist/internal/response.js +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@monarcode/effetch`, newest first.
|
|
4
4
|
|
|
5
|
+
## 0.1.0-alpha.2
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- `make`'s `error` option is now `defaultError`, so it reads differently from
|
|
10
|
+
a call's `error`, which replaces it.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- `query` now accepts values typed with an `interface`. Each property is
|
|
15
|
+
still checked, so a `Date`, a nested object or a function is rejected. The
|
|
16
|
+
new `QueryOf<Q>` type is the constraint; `QueryInput` is unchanged, and the
|
|
17
|
+
option types (`BaseOptions`, `NoBodyRequestOptions`, `RequestOptions`) take
|
|
18
|
+
an optional trailing `Q` parameter that defaults to it.
|
|
19
|
+
- `HttpError.status` and `DecodeError.status` use `Schema.Finite` instead of
|
|
20
|
+
`Schema.Number`. The value is still a `number`, as before.
|
|
21
|
+
|
|
22
|
+
### Documentation
|
|
23
|
+
|
|
24
|
+
- Examples use `Schema.Finite` instead of `Schema.Number`. Through the JSON
|
|
25
|
+
codec, `Schema.Number` decodes `"NaN"`, `"Infinity"` and `"-Infinity"`
|
|
26
|
+
strings into numbers and encodes them back as strings.
|
|
27
|
+
|
|
5
28
|
## 0.1.0-alpha.1
|
|
6
29
|
|
|
7
30
|
First release published from CI with npm provenance. No changes to the
|
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ import type * as Fetch from "@monarcode/effetch";
|
|
|
20
20
|
|
|
21
21
|
declare const api: Fetch.Client;
|
|
22
22
|
|
|
23
|
-
const Todo = Schema.Struct({ id: Schema.
|
|
23
|
+
const Todo = Schema.Struct({ id: Schema.Finite, title: Schema.String });
|
|
24
24
|
|
|
25
25
|
const todo = api.get("/todos/:id", { params: { id: 1 }, output: Todo });
|
|
26
26
|
// Effect<{ readonly id: number; readonly title: string },
|
|
@@ -98,7 +98,7 @@ import * as Schema from "effect/Schema";
|
|
|
98
98
|
import * as Fetch from "@monarcode/effetch";
|
|
99
99
|
|
|
100
100
|
const Todo = Schema.Struct({
|
|
101
|
-
id: Schema.
|
|
101
|
+
id: Schema.Finite,
|
|
102
102
|
title: Schema.String,
|
|
103
103
|
completed: Schema.Boolean,
|
|
104
104
|
});
|
|
@@ -141,7 +141,7 @@ const session: { accessToken?: string } = {};
|
|
|
141
141
|
const make = Fetch.make({
|
|
142
142
|
baseUrl: Config.String("API_URL"),
|
|
143
143
|
headers: { "x-client": "web" },
|
|
144
|
-
|
|
144
|
+
defaultError: ApiError,
|
|
145
145
|
plugins: [
|
|
146
146
|
logger(),
|
|
147
147
|
retry(),
|
|
@@ -159,12 +159,12 @@ export const ApiLive = Layer.effect(Api)(make).pipe(
|
|
|
159
159
|
);
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
| Option
|
|
163
|
-
|
|
|
164
|
-
| `baseUrl`
|
|
165
|
-
| `headers`
|
|
166
|
-
| `
|
|
167
|
-
| `plugins`
|
|
162
|
+
| Option | Description |
|
|
163
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
164
|
+
| `baseUrl` | Prepended to every path that isn't an absolute `http(s)://` URL. A string, or an Effect run once when the client is made (a `Config` works). It can't contain a query string or a fragment. |
|
|
165
|
+
| `headers` | Sent with every request. A call's header of the same name wins. `content-type` and `content-length` are ignored here: they come from each body. |
|
|
166
|
+
| `defaultError` | The schema for non-2xx response bodies of calls without their own `error` (see [Errors](#errors)). |
|
|
167
|
+
| `plugins` | See [Plugins](#plugins). The first one is the outermost. |
|
|
168
168
|
|
|
169
169
|
The client holds on to the `HttpClient`, the `baseUrl` and the services its
|
|
170
170
|
plugins need. Its calls need nothing from the environment, apart from the
|
|
@@ -181,7 +181,7 @@ import type * as Fetch from "@monarcode/effetch";
|
|
|
181
181
|
declare const api: Fetch.Client;
|
|
182
182
|
|
|
183
183
|
const Todo = Schema.Struct({
|
|
184
|
-
id: Schema.
|
|
184
|
+
id: Schema.Finite,
|
|
185
185
|
title: Schema.String,
|
|
186
186
|
done: Schema.Boolean,
|
|
187
187
|
due: Schema.Date,
|
|
@@ -237,6 +237,11 @@ options)` do.
|
|
|
237
237
|
An empty 2xx body (204, `HEAD`) decodes as JSON `null`: use `Schema.Void` for
|
|
238
238
|
endpoints that return nothing.
|
|
239
239
|
|
|
240
|
+
Use `Schema.Finite` rather than `Schema.Number` for numbers. Schemas go through
|
|
241
|
+
Effect's JSON codec, where `Schema.Number` also decodes the strings `"NaN"`,
|
|
242
|
+
`"Infinity"` and `"-Infinity"`, and encodes those values back to strings.
|
|
243
|
+
`Schema.Finite` accepts every JSON number and rejects the rest.
|
|
244
|
+
|
|
240
245
|
`client.httpClient` is the configured `HttpClient` underneath: base URL,
|
|
241
246
|
default headers and plugins, but no status check and no decoding. Use it for
|
|
242
247
|
anything the methods don't cover, such as streaming a response.
|
|
@@ -255,7 +260,7 @@ anything the methods don't cover, such as streaming a response.
|
|
|
255
260
|
- `HttpError.headers` are Effect `Headers`: `authorization`, `set-cookie` and
|
|
256
261
|
other sensitive headers print as `<redacted>`.
|
|
257
262
|
- `HttpError.text` is the raw body. `body` is the body decoded with the
|
|
258
|
-
`error` schema, `undefined` if it didn't match, or the parsed JSON when
|
|
263
|
+
call's `error` schema (or the client's `defaultError`), `undefined` if it didn't match, or the parsed JSON when
|
|
259
264
|
there's no schema. Reading it never fails the call.
|
|
260
265
|
|
|
261
266
|
```ts
|
|
@@ -266,7 +271,7 @@ import type * as Fetch from "@monarcode/effetch";
|
|
|
266
271
|
|
|
267
272
|
declare const api: Fetch.Client;
|
|
268
273
|
|
|
269
|
-
const Todo = Schema.Struct({ id: Schema.
|
|
274
|
+
const Todo = Schema.Struct({ id: Schema.Finite, title: Schema.String });
|
|
270
275
|
const ApiError = Schema.Struct({ code: Schema.String });
|
|
271
276
|
|
|
272
277
|
export const todo = (id: number) =>
|
|
@@ -480,7 +485,7 @@ import * as Schema from "effect/Schema";
|
|
|
480
485
|
|
|
481
486
|
import * as Fetch from "@monarcode/effetch";
|
|
482
487
|
|
|
483
|
-
const Todo = Schema.Struct({ id: Schema.
|
|
488
|
+
const Todo = Schema.Struct({ id: Schema.Finite, title: Schema.String });
|
|
484
489
|
|
|
485
490
|
const sent: Array<string> = [];
|
|
486
491
|
|
|
@@ -571,10 +576,10 @@ page's URL.
|
|
|
571
576
|
[writing plugins](#writing-a-plugin).
|
|
572
577
|
- Option and result types, for wrapping the client in your own functions:
|
|
573
578
|
`RequestOptions`, `NoBodyRequestOptions`, `BaseOptions`, `BodyOptions`,
|
|
574
|
-
`ParamsOption`, `QueryInput`, `
|
|
575
|
-
`Success`, `CallError`, `CallServices`, `CallEffect`,
|
|
576
|
-
`BodyMethod`, `RequestMethod`, `PathParamNames`,
|
|
577
|
-
`PathParamValue`.
|
|
579
|
+
`ParamsOption`, `QueryInput`, `QueryOf`, `QueryValue`, `AnySchema`,
|
|
580
|
+
`Args`, `Success`, `CallError`, `CallServices`, `CallEffect`,
|
|
581
|
+
`NoBodyMethod`, `BodyMethod`, `RequestMethod`, `PathParamNames`,
|
|
582
|
+
`PathParams`, `PathParamValue`.
|
|
578
583
|
|
|
579
584
|
`@monarcode/effetch/plugins`:
|
|
580
585
|
|
package/dist/Client.d.ts
CHANGED
|
@@ -25,8 +25,8 @@ import { Plugin } from "./Plugin.js";
|
|
|
25
25
|
* `content-type` on a call to override it). When a call has an `output`
|
|
26
26
|
* schema, effetch sends `Accept: application/json` unless an `accept`
|
|
27
27
|
* header is set here or on the call.
|
|
28
|
-
* - `
|
|
29
|
-
* `error` option replaces it.
|
|
28
|
+
* - `defaultError`: the schema for non-2xx response bodies of calls that
|
|
29
|
+
* don't pass their own `error` option. A call's `error` replaces it.
|
|
30
30
|
* - `plugins`: hooks into every call (see {@link Plugin}). `plugins[0]` is
|
|
31
31
|
* the outermost layer: its `onRequest` runs first and its `onResponse`
|
|
32
32
|
* last. Names must be unique. Pass the list inline: annotating it as
|
|
@@ -51,7 +51,7 @@ import { Plugin } from "./Plugin.js";
|
|
|
51
51
|
* const make = Fetch.make({
|
|
52
52
|
* baseUrl: Config.String("API_URL"),
|
|
53
53
|
* headers: { accept: "application/json" },
|
|
54
|
-
*
|
|
54
|
+
* defaultError: ApiError,
|
|
55
55
|
* plugins: [apiKey],
|
|
56
56
|
* });
|
|
57
57
|
* ```
|
|
@@ -68,8 +68,8 @@ export interface ClientConfig<
|
|
|
68
68
|
readonly baseUrl?: string | Effect.Effect<string, BaseE, BaseR> | undefined;
|
|
69
69
|
/** Headers sent with every request. */
|
|
70
70
|
readonly headers?: Headers.Input | undefined;
|
|
71
|
-
/**
|
|
72
|
-
readonly
|
|
71
|
+
/** Schema for non-2xx response bodies, unless a call passes its own `error`. */
|
|
72
|
+
readonly defaultError?: EB | undefined;
|
|
73
73
|
/** Plugins, outermost first. Names must be unique. */
|
|
74
74
|
readonly plugins?: Ps | undefined;
|
|
75
75
|
}
|
|
@@ -79,7 +79,7 @@ export interface ClientConfig<
|
|
|
79
79
|
* can fail with the plugins' errors on top of effetch's own.
|
|
80
80
|
*
|
|
81
81
|
* - `Ps`: the plugins the client was made with.
|
|
82
|
-
* - `EB`: the client's
|
|
82
|
+
* - `EB`: the client's `defaultError` schema.
|
|
83
83
|
*
|
|
84
84
|
* @example
|
|
85
85
|
* ```ts
|
|
@@ -87,7 +87,7 @@ export interface ClientConfig<
|
|
|
87
87
|
* import * as Schema from "effect/Schema";
|
|
88
88
|
* import * as Fetch from "@monarcode/effetch";
|
|
89
89
|
*
|
|
90
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
90
|
+
* const Todo = Schema.Struct({ id: Schema.Finite, title: Schema.String });
|
|
91
91
|
*
|
|
92
92
|
* const program = (api: Fetch.Client) =>
|
|
93
93
|
* api.get("/todos/:id", { params: { id: 1 }, output: Todo }).pipe(
|
|
@@ -140,7 +140,7 @@ export interface Client<
|
|
|
140
140
|
* import * as Schema from "effect/Schema";
|
|
141
141
|
* import * as Fetch from "@monarcode/effetch";
|
|
142
142
|
*
|
|
143
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
143
|
+
* const Todo = Schema.Struct({ id: Schema.Finite, done: Schema.Boolean });
|
|
144
144
|
*
|
|
145
145
|
* const complete = (api: Fetch.Client, id: number) =>
|
|
146
146
|
* api.request("PATCH", "/todos/:id", {
|
|
@@ -159,7 +159,7 @@ export interface Client<
|
|
|
159
159
|
* import * as Schema from "effect/Schema";
|
|
160
160
|
* import * as Fetch from "@monarcode/effetch";
|
|
161
161
|
*
|
|
162
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
162
|
+
* const Todo = Schema.Struct({ id: Schema.Finite, title: Schema.String });
|
|
163
163
|
*
|
|
164
164
|
* const list = (api: Fetch.Client) =>
|
|
165
165
|
* api.get("/todos", {
|
|
@@ -212,7 +212,7 @@ export interface Client<
|
|
|
212
212
|
* import * as Fetch from "@monarcode/effetch";
|
|
213
213
|
*
|
|
214
214
|
* const NewTodo = Schema.Struct({ title: Schema.String, due: Schema.Date });
|
|
215
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
215
|
+
* const Todo = Schema.Struct({ id: Schema.Finite, title: Schema.String });
|
|
216
216
|
*
|
|
217
217
|
* const create = (api: Fetch.Client) =>
|
|
218
218
|
* api.post("/todos", {
|
|
@@ -238,7 +238,7 @@ export interface Client<
|
|
|
238
238
|
* import * as Schema from "effect/Schema";
|
|
239
239
|
* import * as Fetch from "@monarcode/effetch";
|
|
240
240
|
*
|
|
241
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
241
|
+
* const Todo = Schema.Struct({ id: Schema.Finite, title: Schema.String });
|
|
242
242
|
*
|
|
243
243
|
* const replace = (api: Fetch.Client, todo: typeof Todo.Type) =>
|
|
244
244
|
* api.put("/todos/:id", {
|
|
@@ -259,7 +259,7 @@ export interface Client<
|
|
|
259
259
|
* import * as Schema from "effect/Schema";
|
|
260
260
|
* import * as Fetch from "@monarcode/effetch";
|
|
261
261
|
*
|
|
262
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
262
|
+
* const Todo = Schema.Struct({ id: Schema.Finite, done: Schema.Boolean });
|
|
263
263
|
*
|
|
264
264
|
* const complete = (api: Fetch.Client, id: number) =>
|
|
265
265
|
* api.patch("/todos/:id", {
|
package/dist/Client.js
CHANGED
|
@@ -87,7 +87,7 @@ const make = (config = {}) => Effect.gen(function* () {
|
|
|
87
87
|
const chain = applyPlugins(mapClientErrors(provided), plugins, context);
|
|
88
88
|
const httpClient = HttpClient.mapRequestInput(HttpClient.transformResponse(chain, provideOverrides(void 0)), applyDefaults);
|
|
89
89
|
const call = makeCall({
|
|
90
|
-
errorSchema: config.
|
|
90
|
+
errorSchema: config.defaultError,
|
|
91
91
|
applyDefaults,
|
|
92
92
|
chain,
|
|
93
93
|
plugins,
|
package/dist/Errors.d.ts
CHANGED
|
@@ -46,7 +46,7 @@ declare const HttpError_base: Schema.Class<
|
|
|
46
46
|
{
|
|
47
47
|
readonly method: Schema.String;
|
|
48
48
|
readonly url: Schema.String;
|
|
49
|
-
readonly status: Schema.
|
|
49
|
+
readonly status: Schema.Finite;
|
|
50
50
|
readonly headers: Schema.declare<Headers.Headers, unknown>;
|
|
51
51
|
readonly text: Schema.String;
|
|
52
52
|
readonly body: Schema.Unknown;
|
|
@@ -68,7 +68,8 @@ declare const HttpError_base: Schema.Class<
|
|
|
68
68
|
* sensitive ones (`set-cookie`, `authorization`, …) print as
|
|
69
69
|
* `<redacted>` when the error is logged or serialised.
|
|
70
70
|
* - `text` is always the raw response body (`""` if it couldn't be read).
|
|
71
|
-
* - `body` is the body decoded with the call's (or client's
|
|
71
|
+
* - `body` is the body decoded with the call's `error` schema (or the client's
|
|
72
|
+
* `defaultError`),
|
|
72
73
|
* or `undefined` if it didn't match. Without an `error` schema, `body` is
|
|
73
74
|
* the parsed JSON when `text` is valid JSON, else `undefined`. An empty
|
|
74
75
|
* body is always `undefined`. Reading `body` never fails the call.
|
|
@@ -140,7 +141,7 @@ declare const DecodeError_base: Schema.Class<
|
|
|
140
141
|
{
|
|
141
142
|
readonly method: Schema.String;
|
|
142
143
|
readonly url: Schema.String;
|
|
143
|
-
readonly status: Schema.
|
|
144
|
+
readonly status: Schema.Finite;
|
|
144
145
|
readonly issue: Schema.Unknown;
|
|
145
146
|
readonly message: Schema.String;
|
|
146
147
|
}
|
package/dist/Errors.js
CHANGED
|
@@ -48,7 +48,8 @@ var NetworkError = class extends Schema.TaggedError()("NetworkError", {
|
|
|
48
48
|
* sensitive ones (`set-cookie`, `authorization`, …) print as
|
|
49
49
|
* `<redacted>` when the error is logged or serialised.
|
|
50
50
|
* - `text` is always the raw response body (`""` if it couldn't be read).
|
|
51
|
-
* - `body` is the body decoded with the call's (or client's
|
|
51
|
+
* - `body` is the body decoded with the call's `error` schema (or the client's
|
|
52
|
+
* `defaultError`),
|
|
52
53
|
* or `undefined` if it didn't match. Without an `error` schema, `body` is
|
|
53
54
|
* the parsed JSON when `text` is valid JSON, else `undefined`. An empty
|
|
54
55
|
* body is always `undefined`. Reading `body` never fails the call.
|
|
@@ -80,7 +81,7 @@ var NetworkError = class extends Schema.TaggedError()("NetworkError", {
|
|
|
80
81
|
var HttpError = class extends Schema.TaggedError()("HttpError", {
|
|
81
82
|
method: Schema.String,
|
|
82
83
|
url: Schema.String,
|
|
83
|
-
status: Schema.
|
|
84
|
+
status: Schema.Finite,
|
|
84
85
|
headers: Schema.declare(Headers.isHeaders),
|
|
85
86
|
text: Schema.String,
|
|
86
87
|
body: Schema.Unknown
|
|
@@ -124,7 +125,7 @@ var HttpError = class extends Schema.TaggedError()("HttpError", {
|
|
|
124
125
|
var DecodeError = class extends Schema.TaggedError()("DecodeError", {
|
|
125
126
|
method: Schema.String,
|
|
126
127
|
url: Schema.String,
|
|
127
|
-
status: Schema.
|
|
128
|
+
status: Schema.Finite,
|
|
128
129
|
issue: Schema.Unknown,
|
|
129
130
|
message: Schema.String
|
|
130
131
|
}) {};
|
package/dist/Options.d.ts
CHANGED
|
@@ -46,6 +46,33 @@ export type QueryValue = UrlParams.Coercible;
|
|
|
46
46
|
export type QueryInput = {
|
|
47
47
|
readonly [key: string]: QueryValue | ReadonlyArray<QueryValue>;
|
|
48
48
|
};
|
|
49
|
+
/**
|
|
50
|
+
* The constraint on a `query` of type `Q`: each of `Q`'s own properties must
|
|
51
|
+
* be a {@link QueryValue} or an array of them.
|
|
52
|
+
*
|
|
53
|
+
* Unlike {@link QueryInput}, this has no index signature, so it also accepts
|
|
54
|
+
* values typed with an `interface` (TypeScript never gives interfaces an
|
|
55
|
+
* implicit index signature).
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* import type * as Fetch from "@monarcode/effetch";
|
|
60
|
+
*
|
|
61
|
+
* interface ListTodosParams {
|
|
62
|
+
* readonly limit: number;
|
|
63
|
+
* readonly tags?: ReadonlyArray<string> | undefined;
|
|
64
|
+
* }
|
|
65
|
+
*
|
|
66
|
+
* declare const params: ListTodosParams;
|
|
67
|
+
*
|
|
68
|
+
* const query: Fetch.QueryOf<ListTodosParams> = params;
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @since 0.1.0
|
|
72
|
+
*/
|
|
73
|
+
export type QueryOf<Q> = {
|
|
74
|
+
readonly [K in keyof Q]: QueryValue | ReadonlyArray<QueryValue>;
|
|
75
|
+
};
|
|
49
76
|
/**
|
|
50
77
|
* Any Effect schema accepted by the `output`, `error` and `input` options.
|
|
51
78
|
*
|
|
@@ -54,7 +81,7 @@ export type QueryInput = {
|
|
|
54
81
|
* import * as Schema from "effect/Schema";
|
|
55
82
|
* import type * as Fetch from "@monarcode/effetch";
|
|
56
83
|
*
|
|
57
|
-
* const Todo: Fetch.AnySchema = Schema.Struct({ id: Schema.
|
|
84
|
+
* const Todo: Fetch.AnySchema = Schema.Struct({ id: Schema.Finite });
|
|
58
85
|
* ```
|
|
59
86
|
*
|
|
60
87
|
* @since 0.1.0
|
|
@@ -98,13 +125,15 @@ export type ParamsOption<P extends string> = string extends P
|
|
|
98
125
|
* - `O`: the `output` schema, or `undefined` for the raw response.
|
|
99
126
|
* - `EB`: the `error` schema for non-2xx bodies.
|
|
100
127
|
* - `Ps`: the client's plugins, for the `plugins` override map.
|
|
128
|
+
* - `Q`: the type of `query`, checked with {@link QueryOf}. Defaults to
|
|
129
|
+
* {@link QueryInput}.
|
|
101
130
|
*
|
|
102
131
|
* @example
|
|
103
132
|
* ```ts
|
|
104
133
|
* import * as Schema from "effect/Schema";
|
|
105
134
|
* import type * as Fetch from "@monarcode/effetch";
|
|
106
135
|
*
|
|
107
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
136
|
+
* const Todo = Schema.Struct({ id: Schema.Finite });
|
|
108
137
|
*
|
|
109
138
|
* const options: Fetch.BaseOptions<typeof Todo, Schema.Unknown, []> = {
|
|
110
139
|
* query: { expand: "owner" },
|
|
@@ -119,9 +148,10 @@ export interface BaseOptions<
|
|
|
119
148
|
O extends AnySchema | undefined,
|
|
120
149
|
EB extends AnySchema,
|
|
121
150
|
Ps extends ReadonlyArray<Plugin.Any>,
|
|
151
|
+
Q extends QueryOf<Q> = QueryInput,
|
|
122
152
|
> {
|
|
123
153
|
/** Query parameters. Arrays repeat the key; `null`/`undefined` are dropped. */
|
|
124
|
-
readonly query?:
|
|
154
|
+
readonly query?: Q | undefined;
|
|
125
155
|
/** Headers for this call, merged over the client's headers. */
|
|
126
156
|
readonly headers?: Headers.Input | undefined;
|
|
127
157
|
/**
|
|
@@ -198,8 +228,9 @@ export type NoBodyRequestOptions<
|
|
|
198
228
|
O extends AnySchema | undefined,
|
|
199
229
|
EB extends AnySchema,
|
|
200
230
|
Ps extends ReadonlyArray<Plugin.Any>,
|
|
231
|
+
Q extends QueryOf<Q> = QueryInput,
|
|
201
232
|
> = ParamsOption<P> &
|
|
202
|
-
BaseOptions<O, EB, Ps> & {
|
|
233
|
+
BaseOptions<O, EB, Ps, Q> & {
|
|
203
234
|
readonly body?: undefined;
|
|
204
235
|
readonly input?: undefined;
|
|
205
236
|
};
|
|
@@ -225,7 +256,8 @@ export type RequestOptions<
|
|
|
225
256
|
EB extends AnySchema,
|
|
226
257
|
I extends AnySchema,
|
|
227
258
|
Ps extends ReadonlyArray<Plugin.Any>,
|
|
228
|
-
|
|
259
|
+
Q extends QueryOf<Q> = QueryInput,
|
|
260
|
+
> = ParamsOption<P> & BaseOptions<O, EB, Ps, Q> & BodyOptions<I>;
|
|
229
261
|
/**
|
|
230
262
|
* The rest arguments after the path: the options object `T` is required
|
|
231
263
|
* when path `P` has parameters, optional otherwise.
|
|
@@ -254,7 +286,7 @@ export type Args<P extends string, T> = [PathParamNames<P>] extends [never]
|
|
|
254
286
|
* import * as Schema from "effect/Schema";
|
|
255
287
|
* import type * as Fetch from "@monarcode/effetch";
|
|
256
288
|
*
|
|
257
|
-
* type Todo = Fetch.Success<Schema.Struct<{ id: Schema.
|
|
289
|
+
* type Todo = Fetch.Success<Schema.Struct<{ id: Schema.Finite }>>;
|
|
258
290
|
* // ^? { readonly id: number }
|
|
259
291
|
* ```
|
|
260
292
|
*
|
|
@@ -274,7 +306,7 @@ export type Success<O extends AnySchema | undefined> = O extends AnySchema
|
|
|
274
306
|
* import type * as Fetch from "@monarcode/effetch";
|
|
275
307
|
*
|
|
276
308
|
* type E = Fetch.CallError<
|
|
277
|
-
* Schema.Struct<{ id: Schema.
|
|
309
|
+
* Schema.Struct<{ id: Schema.Finite }>,
|
|
278
310
|
* Schema.Struct<{ code: Schema.String }>,
|
|
279
311
|
* []
|
|
280
312
|
* >;
|
|
@@ -302,7 +334,7 @@ export type CallError<
|
|
|
302
334
|
* import type * as Fetch from "@monarcode/effetch";
|
|
303
335
|
*
|
|
304
336
|
* type R = Fetch.CallServices<
|
|
305
|
-
* Schema.Struct<{ id: Schema.
|
|
337
|
+
* Schema.Struct<{ id: Schema.Finite }>,
|
|
306
338
|
* Schema.Unknown,
|
|
307
339
|
* Schema.Unknown
|
|
308
340
|
* >;
|
|
@@ -334,7 +366,7 @@ export type CallServices<
|
|
|
334
366
|
* import type * as Fetch from "@monarcode/effetch";
|
|
335
367
|
*
|
|
336
368
|
* type Call = Fetch.CallEffect<
|
|
337
|
-
* Schema.Struct<{ id: Schema.
|
|
369
|
+
* Schema.Struct<{ id: Schema.Finite }>,
|
|
338
370
|
* Schema.Unknown,
|
|
339
371
|
* Schema.Unknown,
|
|
340
372
|
* []
|
|
@@ -354,7 +386,8 @@ export type CallEffect<
|
|
|
354
386
|
* The signature of `get`, `head` and `options`: no `body` or `input`.
|
|
355
387
|
*
|
|
356
388
|
* - `Ps`: the client's plugins.
|
|
357
|
-
* - `DefaultEB`: the client's `
|
|
389
|
+
* - `DefaultEB`: the client's `defaultError` schema, used when a call has
|
|
390
|
+
* no `error`.
|
|
358
391
|
*
|
|
359
392
|
* @example
|
|
360
393
|
* ```ts
|
|
@@ -363,7 +396,7 @@ export type CallEffect<
|
|
|
363
396
|
*
|
|
364
397
|
* declare const get: Fetch.NoBodyMethod<[], Schema.Unknown>;
|
|
365
398
|
*
|
|
366
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
399
|
+
* const Todo = Schema.Struct({ id: Schema.Finite });
|
|
367
400
|
* const todo = get("/todos/:id", { params: { id: 1 }, output: Todo });
|
|
368
401
|
* ```
|
|
369
402
|
*
|
|
@@ -377,9 +410,10 @@ export interface NoBodyMethod<
|
|
|
377
410
|
P extends string,
|
|
378
411
|
O extends AnySchema | undefined = undefined,
|
|
379
412
|
EB extends AnySchema = DefaultEB,
|
|
413
|
+
Q extends QueryOf<Q> = QueryInput,
|
|
380
414
|
>(
|
|
381
415
|
path: P,
|
|
382
|
-
...args: Args<P, NoBodyRequestOptions<P, O, EB, Ps>>
|
|
416
|
+
...args: Args<P, NoBodyRequestOptions<P, O, EB, Ps, Q>>
|
|
383
417
|
): CallEffect<O, EB, Schema.Unknown, Ps>;
|
|
384
418
|
}
|
|
385
419
|
/**
|
|
@@ -387,7 +421,8 @@ export interface NoBodyMethod<
|
|
|
387
421
|
* typed by `input` when given.
|
|
388
422
|
*
|
|
389
423
|
* - `Ps`: the client's plugins.
|
|
390
|
-
* - `DefaultEB`: the client's `
|
|
424
|
+
* - `DefaultEB`: the client's `defaultError` schema, used when a call has
|
|
425
|
+
* no `error`.
|
|
391
426
|
*
|
|
392
427
|
* @example
|
|
393
428
|
* ```ts
|
|
@@ -396,7 +431,7 @@ export interface NoBodyMethod<
|
|
|
396
431
|
*
|
|
397
432
|
* declare const patch: Fetch.BodyMethod<[], Schema.Unknown>;
|
|
398
433
|
*
|
|
399
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
434
|
+
* const Todo = Schema.Struct({ id: Schema.Finite, done: Schema.Boolean });
|
|
400
435
|
* const updated = patch("/todos/:id", {
|
|
401
436
|
* params: { id: 1 },
|
|
402
437
|
* body: { done: true },
|
|
@@ -415,9 +450,10 @@ export interface BodyMethod<
|
|
|
415
450
|
O extends AnySchema | undefined = undefined,
|
|
416
451
|
EB extends AnySchema = DefaultEB,
|
|
417
452
|
I extends AnySchema = Schema.Unknown,
|
|
453
|
+
Q extends QueryOf<Q> = QueryInput,
|
|
418
454
|
>(
|
|
419
455
|
path: P,
|
|
420
|
-
...args: Args<P, RequestOptions<P, O, EB, I, Ps>>
|
|
456
|
+
...args: Args<P, RequestOptions<P, O, EB, I, Ps, Q>>
|
|
421
457
|
): CallEffect<O, EB, I, Ps>;
|
|
422
458
|
}
|
|
423
459
|
/**
|
|
@@ -425,7 +461,8 @@ export interface BodyMethod<
|
|
|
425
461
|
* `input` when given.
|
|
426
462
|
*
|
|
427
463
|
* - `Ps`: the client's plugins.
|
|
428
|
-
* - `DefaultEB`: the client's `
|
|
464
|
+
* - `DefaultEB`: the client's `defaultError` schema, used when a call has
|
|
465
|
+
* no `error`.
|
|
429
466
|
*
|
|
430
467
|
* @example
|
|
431
468
|
* ```ts
|
|
@@ -434,7 +471,7 @@ export interface BodyMethod<
|
|
|
434
471
|
*
|
|
435
472
|
* declare const request: Fetch.RequestMethod<[], Schema.Unknown>;
|
|
436
473
|
*
|
|
437
|
-
* const Todo = Schema.Struct({ id: Schema.
|
|
474
|
+
* const Todo = Schema.Struct({ id: Schema.Finite, done: Schema.Boolean });
|
|
438
475
|
* const updated = request("PATCH", "/todos/:id", {
|
|
439
476
|
* params: { id: 1 },
|
|
440
477
|
* body: { done: true },
|
|
@@ -453,10 +490,11 @@ export interface RequestMethod<
|
|
|
453
490
|
O extends AnySchema | undefined = undefined,
|
|
454
491
|
EB extends AnySchema = DefaultEB,
|
|
455
492
|
I extends AnySchema = Schema.Unknown,
|
|
493
|
+
Q extends QueryOf<Q> = QueryInput,
|
|
456
494
|
>(
|
|
457
495
|
method: HttpMethod.HttpMethod,
|
|
458
496
|
path: P,
|
|
459
|
-
...args: Args<P, RequestOptions<P, O, EB, I, Ps>>
|
|
497
|
+
...args: Args<P, RequestOptions<P, O, EB, I, Ps, Q>>
|
|
460
498
|
): CallEffect<O, EB, I, Ps>;
|
|
461
499
|
}
|
|
462
500
|
//#endregion
|
package/dist/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
NoBodyRequestOptions,
|
|
20
20
|
ParamsOption,
|
|
21
21
|
QueryInput,
|
|
22
|
+
QueryOf,
|
|
22
23
|
QueryValue,
|
|
23
24
|
RequestMethod,
|
|
24
25
|
RequestOptions,
|
|
@@ -50,6 +51,7 @@ export {
|
|
|
50
51
|
type Plugin,
|
|
51
52
|
type PluginContext,
|
|
52
53
|
type QueryInput,
|
|
54
|
+
type QueryOf,
|
|
53
55
|
type QueryValue,
|
|
54
56
|
type RequestMethod,
|
|
55
57
|
type RequestOptions,
|
package/dist/internal/body.js
CHANGED
|
@@ -61,7 +61,7 @@ const encodePlain = (body) => {
|
|
|
61
61
|
* `Invalid request body:` and whose `cause` is the underlying error.
|
|
62
62
|
*/
|
|
63
63
|
const encodeBody = (body, input) => {
|
|
64
|
-
if (body === void 0) return Effect.
|
|
64
|
+
if (body === void 0) return Effect.undefined;
|
|
65
65
|
if (input !== void 0) return orDieInvalid(HttpBody.jsonSchema(input)(body));
|
|
66
66
|
return encodePlain(body);
|
|
67
67
|
};
|
|
@@ -17,7 +17,7 @@ const readErrorBody = (text, schema) => {
|
|
|
17
17
|
try {
|
|
18
18
|
json = parseBody(text);
|
|
19
19
|
} catch {
|
|
20
|
-
return Effect.
|
|
20
|
+
return Effect.undefined;
|
|
21
21
|
}
|
|
22
22
|
if (json === void 0 || schema === void 0) return Effect.succeed(json);
|
|
23
23
|
return Effect.orElseSucceed(decodeJson(schema)(json), () => void 0);
|
|
@@ -27,14 +27,14 @@ function checkStatus(response, errorSchema) {
|
|
|
27
27
|
return Effect.gen(function* () {
|
|
28
28
|
const text = yield* Effect.orElseSucceed(response.text, () => "");
|
|
29
29
|
const body = yield* readErrorBody(text, errorSchema);
|
|
30
|
-
return yield*
|
|
30
|
+
return yield* new HttpError({
|
|
31
31
|
method: response.request.method,
|
|
32
32
|
url: errorUrl(response.request.url),
|
|
33
33
|
status: response.status,
|
|
34
34
|
headers: response.headers,
|
|
35
35
|
text,
|
|
36
36
|
body
|
|
37
|
-
})
|
|
37
|
+
});
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
/**
|
package/package.json
CHANGED