Skip to content

Commit a83e547

Browse files
author
Marcos Defendi
committed
chore: throw error if type is wrong
1 parent 171cef9 commit a83e547

File tree

5 files changed

+156
-37
lines changed

5 files changed

+156
-37
lines changed

apps/meteor/app/api/server/definition.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ export type TypedOptions = {
238238
query?: ValidateFunction;
239239
body?: ValidateFunction;
240240
tags?: string[];
241+
typed?: boolean;
241242
} & Options;
242243

243244
export type TypedThis<TOptions extends TypedOptions, TPath extends string = ''> = {

apps/meteor/app/api/server/router.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,13 @@ export class Router<
158158
);
159159
if (process.env.NODE_ENV === 'test' || process.env.TEST_MODE) {
160160
const responseValidatorFn = options?.response?.[statusCode];
161-
if (!responseValidatorFn) {
162-
console.warn(`Missing response validator for endpoint ${req.method} - ${req.url} with status code ${statusCode}`);
161+
if (!responseValidatorFn && options.typed) {
162+
throw new Error(`Missing response validator for endpoint ${req.method} - ${req.url} with status code ${statusCode}`);
163163
}
164-
if (responseValidatorFn && !responseValidatorFn(body)) {
165-
console.warn(`Invalid response for endpoint ${req.method} - ${req.url}`, responseValidatorFn.errors);
164+
if (responseValidatorFn && !responseValidatorFn(body) && options.typed) {
165+
throw new Error(
166+
`Invalid response for endpoint ${req.method} - ${req.url}. Error: ${responseValidatorFn.errors?.map((error: any) => error.message).join('\n ')}`,
167+
);
166168
}
167169
}
168170

apps/meteor/app/api/server/v1/custom-sounds.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ API.v1.get(
6060
},
6161
query: isCustomSoundsListProps,
6262
authRequired: true,
63+
typed: true,
6364
},
6465
async function action() {
6566
const { offset, count } = await getPaginationItems(this.queryParams as Record<string, string | number | null | undefined>);

apps/meteor/app/api/server/v1/federation.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,15 @@ API.v1
2424
},
2525
additionalProperties: false,
2626
},
27+
success: {
28+
type: 'boolean',
29+
description: 'Indicates if the request was successful.',
30+
},
2731
},
28-
required: ['results'],
32+
required: ['results', 'success'],
2933
}),
3034
},
35+
typed: true,
3136
},
3237
async function () {
3338
const { matrixIds } = this.queryParams;
@@ -50,18 +55,27 @@ API.v1
5055
properties: {
5156
externalReachability: { type: 'object', properties: { ok: { type: 'boolean' } }, required: ['ok'] },
5257
appservice: { type: 'object', properties: { ok: { type: 'boolean' } }, required: ['ok'] },
58+
success: {
59+
type: 'boolean',
60+
description: 'Indicates if the request was successful.',
61+
},
5362
},
54-
required: ['externalReachability', 'appservice'],
63+
required: ['externalReachability', 'appservice', 'success'],
5564
}),
5665
400: ajv.compile({
5766
type: 'object',
5867
properties: {
5968
externalReachability: { type: 'object', properties: { ok: { type: 'boolean' } }, required: ['ok'] },
6069
appservice: { type: 'object', properties: { ok: { type: 'boolean' } }, required: ['ok'] },
70+
success: {
71+
type: 'boolean',
72+
description: 'Indicates if the request was successful.',
73+
},
6174
},
62-
required: ['externalReachability', 'appservice'],
75+
required: ['externalReachability', 'appservice', 'success'],
6376
}),
6477
},
78+
typed: true,
6579
},
6680
async () => {
6781
const service = License.hasValidLicense() ? FederationEE : Federation;

apps/meteor/app/api/server/v1/invites.ts

Lines changed: 131 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,68 @@ API.v1
2323
response: {
2424
200: ajv.compile({
2525
additionalProperties: false,
26-
type: 'object',
27-
properties: {
28-
invites: {
29-
type: 'array',
30-
items: {
26+
type: 'array',
27+
items: {
28+
type: 'object',
29+
properties: {
30+
_id: {
31+
type: 'string',
32+
},
33+
days: {
34+
type: 'number',
35+
},
36+
rid: {
37+
type: 'string',
38+
},
39+
userId: {
40+
type: 'string',
41+
},
42+
createdAt: {
43+
type: 'object',
44+
},
45+
expires: {
46+
type: 'object',
47+
},
48+
url: {
49+
type: 'string',
50+
},
51+
_updatedAt: {
3152
type: 'object',
32-
properties: {
33-
_id: {
34-
type: 'string',
35-
},
36-
rid: {
37-
type: 'string',
38-
},
39-
createdAt: {
40-
type: 'string',
41-
},
42-
expireAt: {
43-
type: 'string',
44-
},
45-
maxUses: {
46-
type: 'number',
47-
},
48-
uses: {
49-
type: 'number',
50-
},
51-
},
52-
required: ['_id', 'rid', 'createdAt', 'expireAt', 'maxUses', 'uses'],
53+
},
54+
maxUses: {
55+
type: 'number',
56+
},
57+
uses: {
58+
type: 'number',
5359
},
5460
},
61+
required: ['_id', 'days', 'rid', 'userId', 'createdAt', 'expires', 'url', '_updatedAt', 'maxUses', 'uses'],
5562
},
56-
required: ['invites'],
63+
}),
64+
401: ajv.compile({
65+
additionalProperties: false,
66+
type: 'object',
67+
properties: {
68+
error: {
69+
type: 'string',
70+
},
71+
status: {
72+
type: 'string',
73+
nullable: true,
74+
},
75+
message: {
76+
type: 'string',
77+
nullable: true,
78+
},
79+
success: {
80+
type: 'boolean',
81+
description: 'Indicates if the request was successful.',
82+
},
83+
},
84+
required: ['success', 'error'],
5785
}),
5886
},
87+
typed: true,
5988
},
6089

6190
async function () {
@@ -79,22 +108,94 @@ API.v1
79108
rid: {
80109
type: 'string',
81110
},
82-
createdAt: {
111+
userId: {
83112
type: 'string',
84113
},
85-
expireAt: {
114+
createdAt: {
115+
type: 'object',
116+
},
117+
_updatedAt: {
118+
type: 'object',
119+
},
120+
expires: {
121+
type: 'object',
122+
},
123+
url: {
86124
type: 'string',
87125
},
88126
maxUses: {
89127
type: 'number',
90128
},
129+
days: {
130+
type: 'number',
131+
},
91132
uses: {
92133
type: 'number',
93134
},
135+
success: {
136+
type: 'boolean',
137+
description: 'Indicates if the request was successful.',
138+
},
139+
},
140+
required: ['_id', 'rid', 'createdAt', 'expires', 'maxUses', 'uses', 'userId', '_updatedAt', 'days', 'success'],
141+
}),
142+
400: ajv.compile({
143+
additionalProperties: false,
144+
type: 'object',
145+
properties: {
146+
error: {
147+
type: 'string',
148+
},
149+
stack: {
150+
type: 'string',
151+
nullable: true,
152+
},
153+
errorType: {
154+
type: 'string',
155+
},
156+
details: {
157+
type: 'object',
158+
nullable: true,
159+
properties: {
160+
rid: {
161+
type: 'string',
162+
},
163+
method: {
164+
type: 'string',
165+
},
166+
},
167+
},
168+
success: {
169+
type: 'boolean',
170+
description: 'Indicates if the request was successful.',
171+
},
172+
},
173+
required: ['success', 'errorType', 'error'],
174+
}),
175+
401: ajv.compile({
176+
additionalProperties: false,
177+
type: 'object',
178+
properties: {
179+
error: {
180+
type: 'string',
181+
},
182+
status: {
183+
type: 'string',
184+
nullable: true,
185+
},
186+
message: {
187+
type: 'string',
188+
nullable: true,
189+
},
190+
success: {
191+
type: 'boolean',
192+
description: 'Indicates if the request was successful.',
193+
},
94194
},
95-
required: ['_id', 'rid', 'createdAt', 'expireAt', 'maxUses', 'uses'],
195+
required: ['success', 'error'],
96196
}),
97197
},
198+
typed: true,
98199
},
99200

100201
async function () {

0 commit comments

Comments
 (0)