Skip to content

Commit

Permalink
Merge body and query into an options object
Browse files Browse the repository at this point in the history
  • Loading branch information
Alduino committed Jul 17, 2022
1 parent 9f409f1 commit 66f2fc6
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 37 deletions.
1 change: 0 additions & 1 deletion project/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 1,3 @@
export type {InferResponse} from "./inferResponse";
export type {ApiResponse} from "./ApiResponse";
export type ApiMap = Record<string, unknown>;
export * from "./real-types";
11 changes: 0 additions & 11 deletions project/src/internal-types.ts

This file was deleted.

7 changes: 6 additions & 1 deletion project/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 76,11 @@ function inferQueryParams(path: string) {
: never`;
}

function inferBody(path: string) {
const id = safifyIdentifier(path);
return `typeof ${id} extends SafeNappiApiHandler<any, string, infer Body> ? Body : unknown`
}

export function nappiPlugin(baseConfig: NextConfig, config: NappiPluginConfig = {}): NextConfig {
const {baseDir = getBaseDir(), tsOut = "types/nappi.d.ts"} = config;

Expand All @@ -94,7 99,7 @@ export function nappiPlugin(baseConfig: NextConfig, config: NappiPluginConfig =
`declare module "${name}" {`,
`export * from "${name}/dist/real-types";`,
...files.flatMap(path => getApiPaths(path).map(apiPath =>
`export function jsonFetch(path: \`${apiPath}\`, query?: (${inferQueryParams(path)}) extends never ? undefined : {[Key in ${inferQueryParams(path)}]?: string}): Promise<${getResponseType(path)}>;`
`export function jsonFetch(path: \`${apiPath}\`, options?: JsonFetchOptions<${inferQueryParams(path)}, ${inferBody(path)}>): Promise<${getResponseType(path)}>;`
)),
"export type ApiResponse<Path extends ",
files.flatMap(path => getApiPaths(path).map(apiPath => `\`${apiPath}\``)).join(" | "),
Expand Down
19 changes: 19 additions & 0 deletions project/src/real-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 9,22 @@ interface NextApiRequestWithData<Query extends string, Body> extends NextApiRequ

export type SafeNappiApiHandler<Response, Query extends string, Body = never> =
(req: NextApiRequestWithData<Query, Body>, res: NextApiResponse<Response>) => unknown | Promise<unknown>;

export type JsonFetchOptions<Query extends string, Body> = unknown extends Body ? {
body?: Body;
query?: {
[Key in Query]?: string;
};
init?: RequestInit;
} : Body extends never ? {
query?: {
[Key in Query]?: string;
};
init?: RequestInit;
} : {
body: Body;
query?: {
[Key in Query]?: string;
};
init?: RequestInit;
};
2 changes: 1 addition & 1 deletion project/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 4,6 @@ export const tsup: Options = {
sourcemap: true,
dts: true,
clean: true,
entryPoints: ["src/index.ts", "src/real-types.ts", "src/internal-types.ts", "src/plugin.ts"],
entryPoints: ["src/index.ts", "src/real-types.ts", "src/plugin.ts"],
format: ["cjs"],
};
4 changes: 3 additions & 1 deletion test/pages/api/users/[id]/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 2,12 @@ import { User } from "lib/types/backend";
import { StandardResponse } from "lib/types/shared";
import {SafeNappiApiHandler} from "safe-nappi";

const handler: SafeNappiApiHandler<StandardResponse<{ user: User }>, "id"> = (
const handler: SafeNappiApiHandler<StandardResponse<{ user: User }>, "id", {foo: "bar"}> = (
req,
res
) => {
console.log(req.body);

const id = req.query.id;
if (typeof id !== "string")
return res.status(400).json({
Expand Down
14 changes: 12 additions & 2 deletions test/pages/unsafeUser.tsx
Original file line number Diff line number Diff line change
@@ -1,8 1,18 @@
import React, { useEffect, useState } from "react";
import { jsonFetch } from "safe-nappi";
import {jsonFetch} from "safe-nappi";

async function doLeFetchificationOfLaDaeeeeeta() {
const data = await jsonFetch("/api/users/fafe?ip=foo&foo=baz");
const data = await jsonFetch("/api/users/fafe", {
body: {
foo: "bar"
},
query: {
id: ""
},
init: {

}
});


}
Expand Down
34 changes: 14 additions & 20 deletions test/types/nappi.d.ts
Original file line number Diff line number Diff line change
@@ -1,53 1,47 @@
import { NextApiHandler } from "next";
import type {default as unsafeUser} from "../pages/api/unsafeUser";
import type {default as users_id_index} from "../pages/api/users/[id]/index";
import type {default as users_index} from "../pages/api/users/index";
import type {default as users_id_index} from "../pages/api/users/[id]/index";
import {SafeNappiApiHandler} from "safe-nappi/dist/real-types";
declare module "safe-nappi" {
export * from "safe-nappi/dist/real-types";
export function jsonFetch(path: `/api/unsafeUser`, query?: (typeof unsafeUser extends SafeNappiApiHandler<any, infer QueryParams>
? QueryParams
: never) extends never ? undefined : {[Key in typeof unsafeUser extends SafeNappiApiHandler<any, infer QueryParams>
export function jsonFetch(path: `/api/unsafeUser`, options?: JsonFetchOptions<typeof unsafeUser extends SafeNappiApiHandler<any, infer QueryParams>
? QueryParams
: never]?: string}): Promise<typeof unsafeUser extends NextApiHandler<infer NextResponse>
: never, typeof unsafeUser extends SafeNappiApiHandler<any, string, infer Body> ? Body : unknown>): Promise<typeof unsafeUser extends NextApiHandler<infer NextResponse>
? NextResponse
: typeof unsafeUser extends SafeNappiApiHandler<infer SnResponse, string>
? SnResponse
: never>;
export function jsonFetch(path: `/api/users/${string}`, query?: (typeof users_id_index extends SafeNappiApiHandler<any, infer QueryParams>
export function jsonFetch(path: `/api/users`, options?: JsonFetchOptions<typeof users_index extends SafeNappiApiHandler<any, infer QueryParams>
? QueryParams
: never) extends never ? undefined : {[Key in typeof users_id_index extends SafeNappiApiHandler<any, infer QueryParams>
? QueryParams
: never]?: string}): Promise<typeof users_id_index extends NextApiHandler<infer NextResponse>
: never, typeof users_index extends SafeNappiApiHandler<any, string, infer Body> ? Body : unknown>): Promise<typeof users_index extends NextApiHandler<infer NextResponse>
? NextResponse
: typeof users_id_index extends SafeNappiApiHandler<infer SnResponse, string>
: typeof users_index extends SafeNappiApiHandler<infer SnResponse, string>
? SnResponse
: never>;
export function jsonFetch(path: `/api/users`, query?: (typeof users_index extends SafeNappiApiHandler<any, infer QueryParams>
? QueryParams
: never) extends never ? undefined : {[Key in typeof users_index extends SafeNappiApiHandler<any, infer QueryParams>
export function jsonFetch(path: `/api/users/${string}`, options?: JsonFetchOptions<typeof users_id_index extends SafeNappiApiHandler<any, infer QueryParams>
? QueryParams
: never]?: string}): Promise<typeof users_index extends NextApiHandler<infer NextResponse>
: never, typeof users_id_index extends SafeNappiApiHandler<any, string, infer Body> ? Body : unknown>): Promise<typeof users_id_index extends NextApiHandler<infer NextResponse>
? NextResponse
: typeof users_index extends SafeNappiApiHandler<infer SnResponse, string>
: typeof users_id_index extends SafeNappiApiHandler<infer SnResponse, string>
? SnResponse
: never>;
export type ApiResponse<Path extends
`/api/unsafeUser` | `/api/users/${string}` | `/api/users`
`/api/unsafeUser` | `/api/users` | `/api/users/${string}`
> =
Path extends `/api/unsafeUser` ? typeof unsafeUser extends NextApiHandler<infer NextResponse>
? NextResponse
: typeof unsafeUser extends SafeNappiApiHandler<infer SnResponse, string>
? SnResponse
: never :
Path extends `/api/users/${string}` ? typeof users_id_index extends NextApiHandler<infer NextResponse>
Path extends `/api/users` ? typeof users_index extends NextApiHandler<infer NextResponse>
? NextResponse
: typeof users_id_index extends SafeNappiApiHandler<infer SnResponse, string>
: typeof users_index extends SafeNappiApiHandler<infer SnResponse, string>
? SnResponse
: never :
Path extends `/api/users` ? typeof users_index extends NextApiHandler<infer NextResponse>
Path extends `/api/users/${string}` ? typeof users_id_index extends NextApiHandler<infer NextResponse>
? NextResponse
: typeof users_index extends SafeNappiApiHandler<infer SnResponse, string>
: typeof users_id_index extends SafeNappiApiHandler<infer SnResponse, string>
? SnResponse
: never :
never;
Expand Down

0 comments on commit 66f2fc6

Please sign in to comment.