11import { Result } from "../utils" ;
2- import { AnyApiEndpoint , AnyApiEndpoints , Method } from "./spec" ;
2+ import { AnyApiEndpoint , AnyApiEndpoints , isMethod , Method } from "./spec" ;
33import { ParsedQs } from "qs" ;
44
55export type Validators <
@@ -25,18 +25,61 @@ export type ValidatorsMap = {
2525 [ Path in string ] : Partial < Record < Method , AnyValidators > > ;
2626} ;
2727
28+ export const runValidators = ( validators : AnyValidators , error : unknown ) => {
29+ const newD = ( ) => Result . data ( undefined ) ;
30+ return {
31+ preCheck : error ,
32+ params : validators . params ?.( ) ?? newD ( ) ,
33+ query : validators . query ?.( ) ?? newD ( ) ,
34+ body : validators . body ?.( ) ?? newD ( ) ,
35+ headers : validators . headers ?.( ) ?? newD ( ) ,
36+ } ;
37+ } ;
38+
39+ export type ResponseValidators <
40+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41+ BodyValidator extends AnyValidator | undefined ,
42+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
43+ HeadersValidator extends AnyValidator | undefined ,
44+ > = {
45+ body : BodyValidator ;
46+ headers : HeadersValidator ;
47+ } ;
48+ export type AnyResponseValidators = Partial <
49+ ResponseValidators < AnyValidator , AnyValidator >
50+ > ;
51+ export const runResponseValidators = ( validators : {
52+ validator : AnyResponseValidators ;
53+ error : unknown ;
54+ } ) => {
55+ const newD = ( ) => Result . data ( undefined ) ;
56+ return {
57+ // TODO: スキーマが間違っていても、bodyのvalidatorがなぜか定義されていない
58+ preCheck : validators . error ,
59+ body : validators . validator . body ?.( ) ?? newD ( ) ,
60+ headers : validators . validator . headers ?.( ) ?? newD ( ) ,
61+ } ;
62+ } ;
63+
2864export type Validator < Data , Error > = ( ) => Result < Data , Error > ;
2965// eslint-disable-next-line @typescript-eslint/no-explicit-any
3066export type AnyValidator = Validator < any , any > ;
3167
3268export type ValidatorsInput = {
3369 path : string ;
3470 method : string ;
35- params ? : Record < string , string > ;
71+ params : Record < string , string | string [ ] > ;
3672 query ?: ParsedQs ;
3773 body ?: Record < string , string > ;
3874 headers : Record < string , string | string [ ] | undefined > ;
3975} ;
76+ export type ResponseValidatorsInput = {
77+ path : string ;
78+ method : string ;
79+ statusCode : number ;
80+ body ?: unknown ;
81+ headers : Headers ;
82+ } ;
4083
4184type ValidationError = {
4285 actual : string ;
@@ -100,3 +143,36 @@ export const getApiSpec = <
100143 const r = validatePathAndMethod ( endpoints , maybePath , maybeMethod ) ;
101144 return Result . map ( r , ( d ) => endpoints [ d . path ] [ d . method ] ) ;
102145} ;
146+
147+ export const preCheck = < E extends AnyApiEndpoints > (
148+ endpoints : E ,
149+ path : string ,
150+ maybeMethod : string ,
151+ ) => {
152+ const method = maybeMethod ?. toLowerCase ( ) ;
153+ if ( ! isMethod ( method ) ) {
154+ return Result . error ( newValidatorMethodNotFoundError ( method ) ) ;
155+ }
156+ return getApiSpec ( endpoints , path , method ) ;
157+ } ;
158+
159+ export type ValidatorError =
160+ | ValidatorMethodNotFoundError
161+ | ValidatorPathNotFoundError ;
162+
163+ export const newValidatorMethodNotFoundError = ( method : string ) => ( {
164+ target : "method" ,
165+ actual : method ,
166+ message : `method does not exist in endpoint` ,
167+ } ) ;
168+ type ValidatorMethodNotFoundError = ReturnType <
169+ typeof newValidatorMethodNotFoundError
170+ > ;
171+ export const newValidatorPathNotFoundError = ( path : string ) => ( {
172+ target : "path" ,
173+ actual : path ,
174+ message : `path does not exist in endpoints` ,
175+ } ) ;
176+ type ValidatorPathNotFoundError = ReturnType <
177+ typeof newValidatorPathNotFoundError
178+ > ;
0 commit comments