Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions apps/meteor/app/api/server/ApiClass.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,23 @@ describe('ExtractRoutesFromAPI', () => {
>;
true as ExpectedFunctionSignature;
});
it('Should extract correct function signature when body is not present', () => {
type APIWithNeverQuery = APIClass<
'/v1',
{
method: 'POST';
path: '/v1/endpoint.test';
response: {
200: ValidateFunction<{
test: string[];
}>;
};
authRequired: true;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make required the definition of body: undefined? I'm afraid people will skit the body definition

also instead of unknown should not be the case of undefined also?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok i will work on that

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we make the body field required in the type definition, it’ll also end up being required for the GET method; because GET and POST are both using the same TypedOptions interface:

export type TypedOptions = {
	response: {
		[K in HTTPStatusCodes]?: ValidateFunction;
	};
	query?: ValidateFunction;
	body: ValidateFunction;
	tags?: string[];
	typed?: boolean;
	license?: LicenseModule[];
} & SharedOptions<'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'>;

To fix this, we could make body optional in the base type and then create a separate type or utility that enforces it only for the methods that actually need it; like POST or PUT. This way, GET stays clean without an unnecessary body

>;
type ExpectedFunctionSignature = Expect<
ShallowEqual<ExtractRoutesFromAPI<APIWithNeverQuery>['/v1/endpoint.test']['POST'], () => { test: string[] }>
>;
true satisfies ExpectedFunctionSignature;
});
});
4 changes: 3 additions & 1 deletion apps/meteor/app/api/server/ApiClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ type ConvertToRoute<TRoute extends MinimalRoute> = {
) => ExtractValidation<Extract<TRoute, { path: K; method: K2 }>['response'][200]>
: K2 extends 'POST'
? (
params: ExtractValidation<Extract<TRoute, { path: K; method: K2 }>['body']>,
...args: [ExtractValidation<Extract<TRoute, { path: K; method: K2 }>['body']>] extends [never]
? [params?: never]
: [params: ExtractValidation<Extract<TRoute, { path: K; method: K2 }>['body']>]
) => ExtractValidation<
200 extends keyof Extract<TRoute, { path: K; method: K2 }>['response']
? Extract<TRoute, { path: K; method: K2 }>['response'][200]
Expand Down
Loading