working on api validator interface

This commit is contained in:
2025-02-04 15:03:39 +03:00
parent 97a5cdf654
commit cbb18d516d
4 changed files with 36 additions and 16 deletions

View File

@ -1,7 +1,14 @@
import { Result } from "@shared/utils/result.ts"; import { type Result } from "@shared/utils/result.ts";
import { Schema } from "@shared/utils/validator.ts"; import { type InferSchema, Schema } from "@shared/utils/validator.ts";
class ApiRoute< export type ExtractRouteParams<T extends string> = T extends string
? T extends `${infer _Start}:${infer Param}/${infer Rest}`
? Param | ExtractRouteParams<Rest>
: T extends `${infer _Start}:${infer Param}` ? Param
: never
: never;
class ClientApi<
Path extends string, Path extends string,
ReqSchema extends Schema<any>, ReqSchema extends Schema<any>,
ResSchema extends Schema<any>, ResSchema extends Schema<any>,
@ -12,12 +19,16 @@ class ApiRoute<
public readonly resSchema: ResSchema, public readonly resSchema: ResSchema,
) { ) {
} }
}
export type ExtractRouteParams<T extends string> = T extends string makeRequest(
? T extends `${infer _Start}:${infer Param}/${infer Rest}` reqBody: InferSchemaType<ReqSchema>,
? Param | ExtractRouteParams<Rest> params?: ExtractRouteParams<Path>,
: T extends `${infer _Start}:${infer Param}` ? Param ) {
: T extends `${infer _Start}*` ? "restOfThePath" const pathWithParams = this.path.split("/").map((segment) => {
: never if (segment.startsWith(":")) {
: never; return params[segment.slice(1)];
}
return segment;
});
}
}

View File

@ -20,7 +20,9 @@ interface IResult<T, E> {
mapErr<U>(fn: (err: E) => U): Result<T, U>; mapErr<U>(fn: (err: E) => U): Result<T, U>;
mapErrAsync<U>(fn: (err: E) => Promise<U>): ResultAsync<T, U>; mapErrAsync<U>(fn: (err: E) => Promise<U>): ResultAsync<T, U>;
andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, E | F>; andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, E | F>;
andThenAsync<U, F>(fn: (value: T) => ResultAsync<U, F>): ResultAsync<U, F>; andThenAsync<U, F>(
fn: (value: T) => ResultAsync<U, F>,
): ResultAsync<U, E | F>;
flatten(): FlattenResult<Result<T, E>>; flatten(): FlattenResult<Result<T, E>>;
flattenOption<U>(errFn: () => U): Result<UnwrapOption<T>, U | E>; flattenOption<U>(errFn: () => U): Result<UnwrapOption<T>, U | E>;
flattenOptionOr<D = UnwrapOption<T>>( flattenOptionOr<D = UnwrapOption<T>>(
@ -119,7 +121,9 @@ export class Ok<T, E> implements IResult<T, E> {
return fn(this.value) as Result<U, E | F>; return fn(this.value) as Result<U, E | F>;
} }
andThenAsync<U, F>(fn: (value: T) => ResultAsync<U, F>): ResultAsync<U, F> { andThenAsync<U, F>(
fn: (value: T) => ResultAsync<U, F>,
): ResultAsync<U, E | F> {
return fn(this.value); return fn(this.value);
} }
@ -254,6 +258,11 @@ export class Err<T, E> implements IResult<T, E> {
andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, E | F> { andThen<U, F>(fn: (value: T) => Result<U, F>): Result<U, E | F> {
return new Err<U, E | F>(this.error); return new Err<U, E | F>(this.error);
} }
andThenAsync<U, F>(
fn: (value: T) => ResultAsync<U, F>,
): ResultAsync<U, E | F> {
return new Err<U, E | F>(this.error).toAsync();
}
flatten(): FlattenResult<Result<T, E>> { flatten(): FlattenResult<Result<T, E>> {
return flattenResult(this); return flattenResult(this);
} }

View File

@ -641,8 +641,6 @@ class NeverSchema extends BaseSchema<never> {
} }
} }
type InferSchemaType<S> = S extends Schema<infer T> ? T : never;
class ObjectSchema<S extends Record<string, Schema<any>>> class ObjectSchema<S extends Record<string, Schema<any>>>
extends BaseSchema<{ [K in keyof S]: InferSchemaType<S[K]> }> { extends BaseSchema<{ [K in keyof S]: InferSchemaType<S[K]> }> {
private strictMode: boolean = false; private strictMode: boolean = false;
@ -1205,3 +1203,5 @@ export const z = {
schema: T, schema: T,
) => new OptionSchema<T>(schema), ) => new OptionSchema<T>(schema),
}; };
export type InferSchemaType<S> = S extends Schema<infer T> ? T : never;

View File

@ -345,7 +345,7 @@ if (res.isErr()) {
} }
// Utility Types // Utility Types
type InferSchema<S> = S extends Schema<infer T> ? T : never; export type InferSchema<S> = S extends Schema<infer T> ? T : never;
type InferSchemaUnion<S extends Schema<any>[]> = S[number] extends type InferSchemaUnion<S extends Schema<any>[]> = S[number] extends
Schema<infer U> ? U : never; Schema<infer U> ? U : never;
type NestedArray<T> = T | NestedArray<T>[]; type NestedArray<T> = T | NestedArray<T>[];