use-query-guard
Version:
A router-agnostic query-string management hook for React with Zod validation
39 lines (36 loc) • 1.84 kB
text/typescript
import z, { ZodObject, ZodRawShape } from 'zod';
type Paramifiable<T> = (T extends string ? string : never) | (T extends number ? number : never) | (T extends boolean ? boolean : never) | string | null;
type UpdateArgs<Schema> = Schema extends ZodObject<ZodRawShape> ? Partial<{
[K in keyof z.infer<Schema>]: Paramifiable<z.infer<Schema>[K]>;
}> : Record<string, string | number | boolean | null>;
interface QueryGuardAdapter {
/** 現在の search 部分 (`?foo=1&bar=2`) を返す */
getSearch(): string;
/** search を pushState/replaceState 相当で更新する */
setSearch(next: string): void;
/** `popstate` 等を購読し、変化時にコールバックを呼ぶ */
subscribe(cb: () => void): () => void;
}
type Optionalise<T> = {
[K in keyof T]: T[K] | undefined;
};
/**
* SearchParamsOptions
* -------------------
* resolver: z.object() スキーマ(無ければゆるい string 辞書)
* preprocess: 読み込み時に key/value を加工
* adapter: URL 操作をフレームワークに合わせて差し替え
*/
type QueryGuardOptions<Schema extends ZodObject<ZodRawShape> | undefined = undefined> = {
resolver?: Schema;
preprocess?: Schema extends ZodObject<ZodRawShape> ? (key: keyof z.infer<Schema> & string, value: string) => string : (key: string, value: string) => string;
adapter?: QueryGuardAdapter;
mode?: 'strict' | 'pick';
};
declare function useQueryGuard<Schema extends ZodObject<ZodRawShape> | undefined = undefined>(options?: QueryGuardOptions<Schema>): {
data: Schema extends ZodObject<ZodRawShape> ? Optionalise<z.infer<Schema>> : Record<string, string | undefined>;
isReady: boolean;
isError: boolean;
updateParams: (params: UpdateArgs<Schema>) => void;
};
export { type QueryGuardAdapter, type QueryGuardOptions, useQueryGuard };