Skip to content

Commit 53d11f7

Browse files
committed
Simplify req/res validator
1 parent 856dadb commit 53d11f7

File tree

4 files changed

+65
-115
lines changed

4 files changed

+65
-115
lines changed

pkgs/typed-api-spec/src/core/validator/request.ts

+1-36
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
import {
2-
AnyApiEndpoints,
32
AnyApiSpec,
43
ApiSpecRequestKey,
54
apiSpecRequestKeys,
65
Method,
76
} from "../spec";
8-
import { Result } from "../../utils";
9-
import {
10-
AnyValidator,
11-
checkValidatorsInput,
12-
ValidatorInputError,
13-
} from "./validate";
7+
import { AnyValidator } from "./validate";
148
import { ParsedQs } from "qs";
159
import { StandardSchemaV1 } from "@standard-schema/spec";
1610

@@ -72,32 +66,3 @@ export const runSpecValidator = (validators: AnySpecValidator | undefined) => {
7266
headers: validators?.headers?.() ?? newD(),
7367
};
7468
};
75-
76-
export type RequestSpecValidatorGenerator = (
77-
input: SpecValidatorGeneratorRawInput<string, string>,
78-
) => Result<AnySpecValidator, ValidatorInputError>;
79-
export type RequestValidatorGenerator = (
80-
spec: AnyApiSpec,
81-
input: SpecValidatorGeneratorInput<string, Method>,
82-
key: ApiSpecRequestKey,
83-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
84-
) => any;
85-
export const createRequestSpecValidatorGenerator = <E extends AnyApiEndpoints>(
86-
endpoints: E,
87-
specValidatorGenerator: RequestValidatorGenerator,
88-
): RequestSpecValidatorGenerator => {
89-
return (
90-
input: SpecValidatorGeneratorRawInput<string, string>,
91-
): Result<AnySpecValidator, ValidatorInputError> => {
92-
const { data: vInput, error } = checkValidatorsInput(endpoints, input);
93-
if (error) {
94-
return Result.error(error);
95-
}
96-
const validators: AnySpecValidator = {};
97-
const spec = endpoints[vInput.path][vInput.method]!;
98-
listDefinedRequestApiSpecKeys(spec).forEach((key) => {
99-
validators[key] = () => specValidatorGenerator(spec, vInput, key);
100-
});
101-
return Result.data(validators);
102-
};
103-
};

pkgs/typed-api-spec/src/core/validator/response.ts

+1-38
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
import {
2-
AnyApiEndpoints,
3-
AnyApiSpec,
42
AnyResponse,
53
ApiSpecResponseKey,
64
apiSpecResponseKeys,
75
Method,
86
} from "../spec";
97
import { StatusCode } from "../hono-types";
108
import { Result } from "../../utils";
11-
import {
12-
AnyValidator,
13-
checkValidatorsInput,
14-
ValidatorInputError,
15-
} from "./validate";
16-
import { AnySpecValidator } from "./request";
9+
import { AnyValidator, ValidatorInputError } from "./validate";
1710
import { StandardSchemaV1 } from "@standard-schema/spec";
1811

1912
export const listDefinedResponseApiSpecKeys = <Response extends AnyResponse>(
@@ -22,36 +15,6 @@ export const listDefinedResponseApiSpecKeys = <Response extends AnyResponse>(
2215
return apiSpecResponseKeys.filter((key) => res[key] !== undefined);
2316
};
2417

25-
export type ResponseSpecValidatorGenerator = (
26-
input: ResponseSpecValidatorGeneratorRawInput<string, string, number>,
27-
) => Result<AnyResponseSpecValidator, ValidatorInputError>;
28-
export type ResponseValidatorGenerator = (
29-
spec: AnyApiSpec,
30-
input: ResponseSpecValidatorGeneratorInput<string, Method, StatusCode>,
31-
key: ApiSpecResponseKey,
32-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
33-
) => any;
34-
export const createResponseSpecValidatorGenerator = <E extends AnyApiEndpoints>(
35-
endpoints: E,
36-
resValidatorGenerator: ResponseValidatorGenerator,
37-
) => {
38-
return (
39-
input: ResponseSpecValidatorGeneratorInput<string, Method, StatusCode>,
40-
): Result<AnyResponseSpecValidator, ValidatorInputError> => {
41-
const { data: vInput, error } = checkValidatorsInput(endpoints, input);
42-
if (error) {
43-
return Result.error(error);
44-
}
45-
const validator: AnySpecValidator = {};
46-
const spec = endpoints[vInput.path][vInput.method]!;
47-
const response = spec?.responses?.[input.statusCode as StatusCode] ?? {};
48-
listDefinedResponseApiSpecKeys(response).forEach((key) => {
49-
validator[key] = () => resValidatorGenerator(spec, input, key);
50-
});
51-
return Result.data(validator);
52-
};
53-
};
54-
5518
export type ResponseSpecValidator<
5619
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5720
BodyValidator extends AnyValidator | undefined,

pkgs/typed-api-spec/src/index.ts

-5
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,4 @@ export * from "./zod";
1818
export {
1919
toOpenApiDoc as toZodOpenApiDoc,
2020
toJsonSchemaApiEndpoints as toZodJsonSchemaApiEndpoints,
21-
ZodOpenApiEndpoints,
22-
ZodOpenApiEndpoint,
23-
ZodAnyOpenApiResponse,
24-
ZodAnyOpenApiResponses,
25-
ZodOpenApiSpec,
2621
} from "./zod/openapi";

pkgs/typed-api-spec/src/ss/index.ts

+63-36
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
import {
2+
AnyResponse,
23
ApiResBody,
34
ApiResHeaders,
4-
ApiResponses,
55
BaseApiSpec,
66
DefineApiResponses,
77
DefineResponse,
88
Method,
99
StatusCode,
1010
} from "../core";
1111
import {
12-
createValidator,
12+
checkValidatorsInput,
1313
Validator,
1414
ValidatorInputError,
1515
} from "../core/validator/validate";
1616
import { Result } from "../utils";
1717
import {
18+
AnySpecValidator,
19+
listDefinedRequestApiSpecKeys,
1820
SpecValidator,
1921
SpecValidatorGeneratorRawInput,
2022
} from "../core/validator/request";
2123
import {
24+
AnyResponseSpecValidator,
25+
listDefinedResponseApiSpecKeys,
2226
ResponseSpecValidator,
23-
ResponseSpecValidatorGeneratorRawInput,
27+
ResponseSpecValidatorGeneratorInput,
2428
} from "../core/validator/response";
2529
import { StandardSchemaV1 } from "@standard-schema/spec";
2630
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -118,46 +122,69 @@ export type ToApiResponses<AR extends SSAnyApiResponses> = {
118122
};
119123
};
120124

121-
type SSRequestValidatorsGenerator<E extends SSApiEndpoints> = <
122-
Path extends string,
123-
M extends string,
124-
>(
125-
input: SpecValidatorGeneratorRawInput<Path, M>,
126-
) => Result<ToSSValidators<E, Path, M>, ValidatorInputError>;
127-
type SSResponseValidatorsGenerator<E extends SSApiEndpoints> = <
128-
Path extends string,
129-
M extends string,
130-
SC extends number,
131-
>(
132-
input: ResponseSpecValidatorGeneratorRawInput<Path, M, SC>,
133-
) => Result<
134-
ToSSResponseValidators<ApiResponses<E, Path, M>, SC>,
135-
ValidatorInputError
136-
>;
137-
138125
/**
139126
* Create a new validator for the given endpoints.
140127
*
141128
* @param endpoints API endpoints
142129
*/
143130
export const newSSValidator = <E extends SSApiEndpoints>(endpoints: E) => {
144-
return createValidator(
145-
endpoints,
146-
async (spec: SSApiSpec, input, key) => {
147-
let r = spec[key]!["~standard"].validate(input[key]);
148-
if (r instanceof Promise) r = await r;
149-
return r;
150-
},
151-
async (spec: SSApiSpec, input, key) => {
152-
const schema = spec["responses"][input.statusCode as StatusCode]?.[key];
153-
let r = schema!["~standard"].validate(input[key]);
154-
if (r instanceof Promise) r = await r;
155-
return r;
156-
},
157-
) as {
158-
req: SSRequestValidatorsGenerator<E>;
159-
res: SSResponseValidatorsGenerator<E>;
131+
const req = (
132+
input: SpecValidatorGeneratorRawInput<string, string>,
133+
): Result<AnySpecValidator, ValidatorInputError> => {
134+
const { data: vInput, error } = checkValidatorsInput(endpoints, input);
135+
if (error) {
136+
return Result.error(error);
137+
}
138+
const validators: AnySpecValidator = {};
139+
const spec = endpoints[vInput.path][vInput.method]!;
140+
listDefinedRequestApiSpecKeys(spec).forEach((key) => {
141+
validators[key] = async () => {
142+
let r = spec[key]!["~standard"].validate(input[key]);
143+
if (r instanceof Promise) r = await r;
144+
return r;
145+
};
146+
});
147+
return Result.data(validators);
148+
};
149+
const res = (
150+
input: ResponseSpecValidatorGeneratorInput<string, Method, StatusCode>,
151+
): Result<AnyResponseSpecValidator, ValidatorInputError> => {
152+
const { data: vInput, error } = checkValidatorsInput(endpoints, input);
153+
if (error) {
154+
return Result.error(error);
155+
}
156+
const validator: AnySpecValidator = {};
157+
const spec = endpoints[vInput.path][vInput.method]!;
158+
const response =
159+
spec?.responses?.[input.statusCode as StatusCode] ?? ({} as AnyResponse);
160+
listDefinedResponseApiSpecKeys(response).forEach((key) => {
161+
validator[key] = async () => {
162+
const schema = spec["responses"][input.statusCode as StatusCode]?.[key];
163+
let r = schema!["~standard"].validate(input[key]);
164+
if (r instanceof Promise) r = await r;
165+
return r;
166+
};
167+
});
168+
return Result.data(validator);
160169
};
170+
return { req, res };
171+
// return createValidator(
172+
// endpoints,
173+
// async (spec: SSApiSpec, input, key) => {
174+
// let r = spec[key]!["~standard"].validate(input[key]);
175+
// if (r instanceof Promise) r = await r;
176+
// return r;
177+
// },
178+
// async (spec: SSApiSpec, input, key) => {
179+
// const schema = spec["responses"][input.statusCode as StatusCode]?.[key];
180+
// let r = schema!["~standard"].validate(input[key]);
181+
// if (r instanceof Promise) r = await r;
182+
// return r;
183+
// },
184+
// ) as {
185+
// req: SSRequestValidatorsGenerator<E>;
186+
// res: SSResponseValidatorsGenerator<E>;
187+
// };
161188
};
162189

163190
// const toResult = <T>(

0 commit comments

Comments
 (0)