denwa-web-shared
Version:
A shared library for Next.js App Router projects containing reusable components, hooks, schemas, and utilities.
64 lines (63 loc) • 3.93 kB
TypeScript
/**
* Минимальная замена zod для внутренних схем пакета.
*
* Почему не zod: обе точки входа пакета (`/server` и `/client`) импортируют его
* статически, а Vite собирает каждую точку входа в один файл. Поэтому у
* потребителя tree-shaking не может выбросить неиспользуемые схемы, и zod
* (~390 КБ в несжатом виде) попадал в бандл каждой страницы любого проекта,
* где из пакета берут хоть что-нибудь — например, `cn`.
*
* Здесь реализован только тот срез API, который нужен схемам пакета:
* `parse` и `safeParse`. Семантика повторяет zod:
* - неизвестные ключи отбрасываются;
* - значения по умолчанию подставляются (`default`);
* - ключ с неопределённым значением в результат не попадает;
* - при несоответствии `parse` бросает `ValidationError`, а `safeParse`
* возвращает `{ success: false, error }`.
*
* Чего нет по сравнению с zod: `z.infer`, `.refine()`, трансформаций и
* разбора строк. Если понадобится что-то из этого — лучше вернуть zod
* отдельной точкой входа, а не растить этот файл.
*/
/** Ошибка валидации. Заменяет `ZodError`. */
export declare class ValidationError extends Error {
constructor(message: string);
}
export type SafeParseResult<T> = {
success: true;
data: T;
} | {
success: false;
error: ValidationError;
};
/** Публичный интерфейс схемы — то, что раньше давал объект zod. */
export interface SchemaLike<T> {
parse: (value: unknown) => T;
safeParse: (value: unknown) => SafeParseResult<T>;
}
/** Проверка одного значения. `path` нужен только для текста ошибки. */
export type Field<T> = (value: unknown, path: string) => T;
export declare const isObject: (value: unknown) => value is Record<string, unknown>;
export declare const isString: (value: unknown) => value is string;
/** `z.number()` в zod не пропускает NaN — повторяем. */
export declare const isNumber: (value: unknown) => value is number;
/** Прерывает валидацию с сообщением, указывающим путь до поля. */
export declare const fail: (path: string, expected: string) => never;
/** `z.string()` */
export declare const str: Field<string>;
/** `z.number()` */
export declare const num: Field<number>;
/** `z.any()` — пропускает всё, включая undefined. */
export declare const anyField: Field<unknown>;
/** `z.string().array()` */
export declare const arr: <T>(field: Field<T>) => Field<T[]>;
/** `z.object({ ... })` — собирает объект только из объявленных ключей. */
export declare const obj: <T extends object>(shape: { [K in keyof T]: Field<T[K]>; }) => Field<T>;
/** `.optional()` */
export declare const optional: <T>(field: Field<T>) => Field<T | undefined>;
/** `.nullable()` */
export declare const nullable: <T>(field: Field<T>) => Field<T | null>;
/** `.default(...)` — подставляет значение только вместо `undefined`. */
export declare const withDefault: <T>(field: Field<T | undefined>, fallback: () => T) => Field<T>;
/** Оборачивает проверку в объект с `parse` / `safeParse`. */
export declare const createSchema: <T>(field: Field<T>) => SchemaLike<T>;