Skip to content

Commit f45aae3

Browse files
feat: make method optional for multi-method endpoints (#90)
* feat: optional method * update README * chore: trigger ci rebuild
1 parent f91495f commit f45aae3

3 files changed

Lines changed: 48 additions & 4 deletions

File tree

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,41 @@ const createItem = createEndpoint("/item", {
158158
})
159159
```
160160

161+
#### Method
162+
163+
You can specify a single HTTP method or an array of methods for an endpoint.
164+
165+
```ts
166+
// Single method
167+
const getItem = createEndpoint("/item", {
168+
method: "GET",
169+
}, async (ctx) => {
170+
return { item: "data" }
171+
})
172+
173+
// Multiple methods
174+
const itemEndpoint = createEndpoint("/item", {
175+
method: ["GET", "POST"],
176+
}, async (ctx) => {
177+
if (ctx.method === "POST") {
178+
// handle POST - create/update
179+
return { created: true }
180+
}
181+
// handle GET - read only
182+
return { item: "data" }
183+
})
184+
```
185+
186+
When calling an endpoint with multiple methods directly (not through HTTP), the `method` parameter is **optional** and defaults to the **first method** in the array:
187+
188+
```ts
189+
// Defaults to "GET" (first in array)
190+
const result = await itemEndpoint({ headers })
191+
192+
// Explicitly specify POST
193+
const result = await itemEndpoint({ headers, method: "POST" })
194+
```
195+
161196
#### Media types
162197

163198
By default, all media types are accepted, but only a handful of them have a built-in support:

src/context.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export type InferMethod<Options extends EndpointOptions> = Options["method"] ext
9292
export type InferInputMethod<
9393
Options extends EndpointOptions,
9494
Method = Options["method"] extends Array<any>
95-
? Options["method"][number]
95+
? Options["method"][number] | undefined
9696
: Options["method"] extends "*"
9797
? HTTPMethod
9898
: Options["method"] | undefined,
@@ -208,7 +208,13 @@ export const createInternalContext = async (
208208
headers: context?.headers,
209209
request: context?.request,
210210
params: "params" in context ? context.params : undefined,
211-
method: context.method,
211+
method:
212+
context.method ??
213+
(Array.isArray(options.method)
214+
? options.method[0]
215+
: options.method === "*"
216+
? "GET"
217+
: options.method),
212218
setHeader: (key: string, value: string) => {
213219
headers.set(key, value);
214220
},

src/endpoint.test.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,11 @@ describe("types", async () => {
354354
expectTypeOf(ctx.method).toEqualTypeOf<"POST" | "GET">();
355355
},
356356
);
357-
//@ts-expect-error - method should be required
357+
// method should be optional for array methods (defaults to first method)
358358
endpoint({});
359+
// but you can still explicitly specify a method
360+
endpoint({ method: "POST" });
361+
endpoint({ method: "GET" });
359362
const wildCardMethodEndpoint = createEndpoint(
360363
"/test",
361364
{
@@ -367,7 +370,7 @@ describe("types", async () => {
367370
>();
368371
},
369372
);
370-
//@ts-expect-error -
373+
//@ts-expect-error - wildcard method should still require explicit method
371374
wildCardMethodEndpoint({});
372375
});
373376
it("response", async () => {

0 commit comments

Comments
 (0)