Skip to content

Commit

Permalink
feat: change api to fetcher.get('/users')
Browse files Browse the repository at this point in the history
  • Loading branch information
KoichiKiyokawa committed Feb 28, 2023
1 parent 6bf8aa0 commit a0ab1f5
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 81 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ export const fetcherObj = createOperationIdFetcher((path, { method, body }) =>
<td>

```ts
const res = await fetcher("/users", {
method: "get",
const res = await fetcher.get("/users", {
query: { per: 10, page: 0 },
});
```
Expand Down
73 changes: 47 additions & 26 deletions src/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -106,30 +106,46 @@ export type OperationIds = keyof operations
type HttpMethods = \\"get\\" | \\"post\\" | \\"put\\" | \\"patch\\" | \\"delete\\" | \\"option\\" | \\"head\\";
type OmitNeverFromRecord<T extends Record<string, unknown>> = Pick<T, {[K in keyof T]: T[K] extends never ? never : K}[keyof T]>
type OmitNeverFromRecord<T extends Record<string, unknown>> = Pick<
T,
{
[K in keyof T]: T[K] extends never ? never : K;
}[keyof T]
>;
type FilterPathsByMethod<Method extends HttpMethods> = {
[P in keyof paths]: Method extends keyof paths[P] ? P : never;
}[keyof paths];
export const createBaseFetcher = (
ownFetcher: (
path: string,
param: {
method: HttpMethods;
body?: Record<string, unknown>;
}
) => Promise<unknown>
},
) => Promise<unknown>,
) => {
return <Path extends keyof paths, Method extends HttpMethods>(
path: Path,
opts: { method: Method } & OmitNeverFromRecord<{
path: Get<paths[Path], [Method, \\"parameters\\", \\"path\\"]>
query: Get<paths[Path], [Method, \\"parameters\\", \\"query\\"]>
body: Get<paths[Path], [Method, \\"requestBody\\", \\"content\\", \\"application/json\\"]>
}>
): Promise<Get<paths[Path], [Method, \\"responses\\", 200, \\"content\\", \\"application/json\\"]>> => {
const { method, query, body } = opts as any
return ownFetcher(
path + (query ? \`?\${new URLSearchParams(query as any)}\` : \\"\\"),
{ method, body }
) as any;
return new Proxy(
{},
{
get:
(_, method: HttpMethods) =>
(path: keyof paths, params: { path: string; query: string; body: Record<string, unknown> }) =>
ownFetcher(path + (params.query ? \`?\${new URLSearchParams(params.query)}\` : \\"\\"), {
method,
body: params.body,
}),
},
) as {
[Method in HttpMethods]: <Path extends FilterPathsByMethod<Method>>(
path: Path,
opts: OmitNeverFromRecord<{
path: Get<paths[Path], [Method, \\"parameters\\", \\"path\\"]>;
query: Get<paths[Path], [Method, \\"parameters\\", \\"query\\"]>;
body: Get<paths[Path], [Method, \\"requestBody\\", \\"content\\", \\"application/json\\"]>;
}>,
) => Promise<Get<paths[Path], [Method, \\"responses\\", 200, \\"content\\", \\"application/json\\"]>>;
};
};
Expand All @@ -139,21 +155,26 @@ export const createOperationIdFetcher = (
param: {
method: HttpMethods;
body?: Record<string, unknown>;
}
) => Promise<unknown>
},
) => Promise<unknown>,
) => {
const baseFetcher = createBaseFetcher(ownFetcher);
const f =
<Path extends keyof paths, Method extends HttpMethods>(p: Path, m: Method) =>
(...o: keyof OmitNeverFromRecord<{
query: Get<paths[Path], [Method, \\"parameters\\", \\"query\\"]>,
body: Get<paths[Path], [Method, \\"requestBody\\", \\"content\\", \\"application/json\\"]>
}> extends never ? [] : [OmitNeverFromRecord<{
query: Get<paths[Path], [Method, \\"parameters\\", \\"query\\"]>,
body: Get<paths[Path], [Method, \\"requestBody\\", \\"content\\", \\"application/json\\"]>
}>]
(
...o: keyof OmitNeverFromRecord<{
query: Get<paths[Path], [Method, \\"parameters\\", \\"query\\"]>;
body: Get<paths[Path], [Method, \\"requestBody\\", \\"content\\", \\"application/json\\"]>;
}> extends never
? []
: [
OmitNeverFromRecord<{
query: Get<paths[Path], [Method, \\"parameters\\", \\"query\\"]>;
body: Get<paths[Path], [Method, \\"requestBody\\", \\"content\\", \\"application/json\\"]>;
}>,
]
): Promise<Get<paths[Path], [Method, \\"responses\\", 200, \\"content\\", \\"application/json\\"]>> =>
baseFetcher(p, { method: m, ...o[0] } as any);
baseFetcher[m](p as any, o[0] as any);
return {
listUsers: f(\\"/users\\", \\"get\\"),
Expand Down
73 changes: 47 additions & 26 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,30 +35,46 @@ export type OperationIds = keyof operations
type HttpMethods = "get" | "post" | "put" | "patch" | "delete" | "option" | "head";
type OmitNeverFromRecord<T extends Record<string, unknown>> = Pick<T, {[K in keyof T]: T[K] extends never ? never : K}[keyof T]>
type OmitNeverFromRecord<T extends Record<string, unknown>> = Pick<
T,
{
[K in keyof T]: T[K] extends never ? never : K;
}[keyof T]
>;
type FilterPathsByMethod<Method extends HttpMethods> = {
[P in keyof paths]: Method extends keyof paths[P] ? P : never;
}[keyof paths];
export const createBaseFetcher = (
ownFetcher: (
path: string,
param: {
method: HttpMethods;
body?: Record<string, unknown>;
}
) => Promise<unknown>
},
) => Promise<unknown>,
) => {
return <Path extends keyof paths, Method extends HttpMethods>(
path: Path,
opts: { method: Method } & OmitNeverFromRecord<{
path: Get<paths[Path], [Method, "parameters", "path"]>
query: Get<paths[Path], [Method, "parameters", "query"]>
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>
}>
): Promise<Get<paths[Path], [Method, "responses", 200, "content", "application/json"]>> => {
const { method, query, body } = opts as any
return ownFetcher(
path + (query ? \`?\${new URLSearchParams(query as any)}\` : ""),
{ method, body }
) as any;
return new Proxy(
{},
{
get:
(_, method: HttpMethods) =>
(path: keyof paths, params: { path: string; query: string; body: Record<string, unknown> }) =>
ownFetcher(path + (params.query ? \`?\${new URLSearchParams(params.query)}\` : ""), {
method,
body: params.body,
}),
},
) as {
[Method in HttpMethods]: <Path extends FilterPathsByMethod<Method>>(
path: Path,
opts: OmitNeverFromRecord<{
path: Get<paths[Path], [Method, "parameters", "path"]>;
query: Get<paths[Path], [Method, "parameters", "query"]>;
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>;
}>,
) => Promise<Get<paths[Path], [Method, "responses", 200, "content", "application/json"]>>;
};
};
Expand All @@ -68,21 +84,26 @@ export const createOperationIdFetcher = (
param: {
method: HttpMethods;
body?: Record<string, unknown>;
}
) => Promise<unknown>
},
) => Promise<unknown>,
) => {
const baseFetcher = createBaseFetcher(ownFetcher);
const f =
<Path extends keyof paths, Method extends HttpMethods>(p: Path, m: Method) =>
(...o: keyof OmitNeverFromRecord<{
query: Get<paths[Path], [Method, "parameters", "query"]>,
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>
}> extends never ? [] : [OmitNeverFromRecord<{
query: Get<paths[Path], [Method, "parameters", "query"]>,
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>
}>]
(
...o: keyof OmitNeverFromRecord<{
query: Get<paths[Path], [Method, "parameters", "query"]>;
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>;
}> extends never
? []
: [
OmitNeverFromRecord<{
query: Get<paths[Path], [Method, "parameters", "query"]>;
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>;
}>,
]
): Promise<Get<paths[Path], [Method, "responses", 200, "content", "application/json"]>> =>
baseFetcher(p, { method: m, ...o[0] } as any);
baseFetcher[m](p as any, o[0] as any);
return {
${[...operationIdToSchemaInfo]
Expand Down
2 changes: 1 addition & 1 deletion test/generated/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("listUsers", () => {
});

test("createBaseFetcher", async () => {
const res = await baseFetcher("/users", { method: "get", query: { per: 10, page: 0 } });
const res = await baseFetcher.get("/users", { query: { per: 10, page: 0 } });

expect(res).toStrictEqual(dummyUsers);
expect(requestSpy).toHaveBeenCalledWith(
Expand Down
73 changes: 47 additions & 26 deletions test/generated/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,30 +103,46 @@ export type OperationIds = keyof operations

type HttpMethods = "get" | "post" | "put" | "patch" | "delete" | "option" | "head";

type OmitNeverFromRecord<T extends Record<string, unknown>> = Pick<T, {[K in keyof T]: T[K] extends never ? never : K}[keyof T]>
type OmitNeverFromRecord<T extends Record<string, unknown>> = Pick<
T,
{
[K in keyof T]: T[K] extends never ? never : K;
}[keyof T]
>;

type FilterPathsByMethod<Method extends HttpMethods> = {
[P in keyof paths]: Method extends keyof paths[P] ? P : never;
}[keyof paths];

export const createBaseFetcher = (
ownFetcher: (
path: string,
param: {
method: HttpMethods;
body?: Record<string, unknown>;
}
) => Promise<unknown>
},
) => Promise<unknown>,
) => {
return <Path extends keyof paths, Method extends HttpMethods>(
path: Path,
opts: { method: Method } & OmitNeverFromRecord<{
path: Get<paths[Path], [Method, "parameters", "path"]>
query: Get<paths[Path], [Method, "parameters", "query"]>
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>
}>
): Promise<Get<paths[Path], [Method, "responses", 200, "content", "application/json"]>> => {
const { method, query, body } = opts as any
return ownFetcher(
path + (query ? `?${new URLSearchParams(query as any)}` : ""),
{ method, body }
) as any;
return new Proxy(
{},
{
get:
(_, method: HttpMethods) =>
(path: keyof paths, params: { path: string; query: string; body: Record<string, unknown> }) =>
ownFetcher(path + (params.query ? `?${new URLSearchParams(params.query)}` : ""), {
method,
body: params.body,
}),
},
) as {
[Method in HttpMethods]: <Path extends FilterPathsByMethod<Method>>(
path: Path,
opts: OmitNeverFromRecord<{
path: Get<paths[Path], [Method, "parameters", "path"]>;
query: Get<paths[Path], [Method, "parameters", "query"]>;
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>;
}>,
) => Promise<Get<paths[Path], [Method, "responses", 200, "content", "application/json"]>>;
};
};

Expand All @@ -136,21 +152,26 @@ export const createOperationIdFetcher = (
param: {
method: HttpMethods;
body?: Record<string, unknown>;
}
) => Promise<unknown>
},
) => Promise<unknown>,
) => {
const baseFetcher = createBaseFetcher(ownFetcher);
const f =
<Path extends keyof paths, Method extends HttpMethods>(p: Path, m: Method) =>
(...o: keyof OmitNeverFromRecord<{
query: Get<paths[Path], [Method, "parameters", "query"]>,
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>
}> extends never ? [] : [OmitNeverFromRecord<{
query: Get<paths[Path], [Method, "parameters", "query"]>,
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>
}>]
(
...o: keyof OmitNeverFromRecord<{
query: Get<paths[Path], [Method, "parameters", "query"]>;
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>;
}> extends never
? []
: [
OmitNeverFromRecord<{
query: Get<paths[Path], [Method, "parameters", "query"]>;
body: Get<paths[Path], [Method, "requestBody", "content", "application/json"]>;
}>,
]
): Promise<Get<paths[Path], [Method, "responses", 200, "content", "application/json"]>> =>
baseFetcher(p, { method: m, ...o[0] } as any);
baseFetcher[m](p as any, o[0] as any);

return {
listUsers: f("/users", "get"),
Expand Down

0 comments on commit a0ab1f5

Please sign in to comment.