Skip to content

Commit 76a383b

Browse files
committed
update: replace all ObjectSanitizers with ObjectValSan
1 parent 4428511 commit 76a383b

8 files changed

Lines changed: 151 additions & 106 deletions

File tree

README.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -212,24 +212,26 @@ For the complete list of error classes, usage examples, and custom error creatio
212212

213213
## Validation & Sanitization
214214

215-
api-machine supports request validation and sanitization using [valsan](https://www.npmjs.com/package/valsan). You can declare ObjectSanitizer members on your endpoint classes for `body`, `query`, `params`, or `headers`:
215+
api-machine supports request validation and sanitization using [valsan](https://www.npmjs.com/package/valsan). You can declare ObjectValSan members on your endpoint classes for `body`, `query`, `params`, or `headers`:
216216

217217
```typescript
218-
import { ObjectSanitizer, EmailValidator } from 'valsan';
218+
import { ObjectValSan, EmailValidator } from 'valsan';
219219
import { NameValSan } from './examples/complete-example/users/name-valsan';
220220

221221
class CreateUserEndpoint extends PostEndpoint {
222-
override path = '/users';
222+
override path = '/users';
223223

224-
override body = new ObjectSanitizer({
225-
name: new NameValSan(),
226-
email: new EmailValidator(),
227-
});
224+
override body = new ObjectValSan({
225+
schema: {
226+
name: new NameValSan(),
227+
email: new EmailValidator(),
228+
}
229+
});
228230

229-
async handle(request, response) {
230-
// request.body is validated & sanitized
231-
// ...
232-
}
231+
async handle(request, response) {
232+
// request.body is validated & sanitized
233+
// ...
234+
}
233235
}
234236
```
235237

examples/complete-example/users/create-user-endpoint.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ApiRequest, ApiResponse, PostEndpoint } from '../../../src/index';
22
import { usersRepo, User } from './users-repository';
3-
import { ObjectSanitizer, EmailValidator, IntegerValidator } from 'valsan';
3+
import { ObjectValSan, EmailValidator, IntegerValidator } from 'valsan';
44
import { NameValSan } from './name-valsan';
55

66
/**
@@ -16,9 +16,11 @@ export class CreateUserEndpoint extends PostEndpoint {
1616
email: 'john@example.com',
1717
};
1818

19-
override body = new ObjectSanitizer({
20-
name: new NameValSan(),
21-
email: new EmailValidator(),
19+
override body = new ObjectValSan({
20+
schema: {
21+
name: new NameValSan(),
22+
email: new EmailValidator(),
23+
},
2224
});
2325

2426
override responseExample = {
@@ -28,10 +30,12 @@ export class CreateUserEndpoint extends PostEndpoint {
2830
created: new Date(),
2931
};
3032

31-
override response = new ObjectSanitizer({
32-
id: new IntegerValidator(),
33-
name: new NameValSan(),
34-
email: new EmailValidator(),
33+
override response = new ObjectValSan({
34+
schema: {
35+
id: new IntegerValidator(),
36+
name: new NameValSan(),
37+
email: new EmailValidator(),
38+
},
3539
});
3640

3741
async handle(request: ApiRequest, response: ApiResponse) {

examples/complete-example/users/get-user-endpoint.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ApiRequest, ApiResponse, GetEndpoint } from '../../../src/index';
22
import { NotFoundError } from '../../../src/error';
33
import { usersRepo } from './users-repository';
4-
import { ObjectSanitizer, IntegerValidator, EmailValidator } from 'valsan';
4+
import { IntegerValidator, EmailValidator, ObjectValSan } from 'valsan';
55
import { NameValSan } from './name-valsan';
66

77
/**
@@ -20,10 +20,12 @@ export class GetUserEndpoint extends GetEndpoint {
2020
created: new Date('2023-01-01'),
2121
};
2222

23-
override response = new ObjectSanitizer({
24-
id: new IntegerValidator(),
25-
name: new NameValSan(),
26-
email: new EmailValidator(),
23+
override response = new ObjectValSan({
24+
schema: {
25+
id: new IntegerValidator(),
26+
name: new NameValSan(),
27+
email: new EmailValidator(),
28+
},
2729
});
2830

2931
async handle(request: ApiRequest, response: ApiResponse) {

examples/complete-example/users/list-users-endpoint.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {
22
ComposedValSan,
33
LengthValidator,
4-
ObjectSanitizer,
4+
ObjectValSan,
55
TrimSanitizer,
66
} from 'valsan';
77
import { ApiRequest, ApiResponse, GetEndpoint } from '../../../src/index';
@@ -16,15 +16,17 @@ import { usersRepo } from './users-repository';
1616
export class ListUsersEndpoint extends GetEndpoint {
1717
override path = '/';
1818

19-
override params = new ObjectSanitizer({
20-
name: new ComposedValSan(
21-
[new TrimSanitizer(), new LengthValidator({ minLength: 3 })],
22-
{ isOptional: true }
23-
),
24-
email: new ComposedValSan(
25-
[new TrimSanitizer(), new LengthValidator({ minLength: 5 })],
26-
{ isOptional: true }
27-
),
19+
override params = new ObjectValSan({
20+
schema: {
21+
name: new ComposedValSan(
22+
[new TrimSanitizer(), new LengthValidator({ minLength: 3 })],
23+
{ isOptional: true }
24+
),
25+
email: new ComposedValSan(
26+
[new TrimSanitizer(), new LengthValidator({ minLength: 5 })],
27+
{ isOptional: true }
28+
),
29+
},
2830
});
2931

3032
async handle(request: ApiRequest, response: ApiResponse) {

src/router/validation-middleware.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ApiRequest, BaseApiEndpoint } from './endpoint';
88
import { UnprocessableEntityError } from '../error';
99

1010
/**
11-
* Runs a valsan ObjectSanitizer on a value,
11+
* Runs a valsan ObjectValSan on a value,
1212
* throws with error details if validation fails.
1313
*/
1414
export async function runSanitizer(
@@ -30,7 +30,7 @@ export async function runSanitizer(
3030
/**
3131
* Validates and sanitizes request parts
3232
* (body, query, params, headers) if the
33-
* endpoint defines a ObjectSanitizers
33+
* endpoint defines an ObjectValSan
3434
*/
3535
export async function validateRequest(
3636
endpoint: BaseApiEndpoint,

test/spec/endpoint/validation.server.ts

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
PostEndpoint,
66
} from '../../../src/router';
77
import {
8-
ObjectSanitizer,
98
EmailValidator,
109
LengthValidator,
1110
StringToNumberValSan,
@@ -48,11 +47,13 @@ export class ValidationRouter extends BaseApiRouter {
4847
class TestQueryParamsEndpoint extends GetEndpoint {
4948
override path = '/query-params';
5049

51-
override query = new ObjectSanitizer({
52-
search: new ComposedValSan([
53-
new TrimSanitizer(),
54-
new LengthValidator({ minLength: 3 }),
55-
]),
50+
override query = new ObjectValSan({
51+
schema: {
52+
search: new ComposedValSan([
53+
new TrimSanitizer(),
54+
new LengthValidator({ minLength: 3 }),
55+
]),
56+
},
5657
});
5758

5859
override async handle(
@@ -64,11 +65,13 @@ export class ValidationRouter extends BaseApiRouter {
6465
class TestRouteParamsEndpoint extends PostEndpoint {
6566
override path = '/route-params/:itemId';
6667

67-
override params = new ObjectSanitizer({
68-
itemId: new ComposedValSan([
69-
new StringToNumberValSan(),
70-
new MinValidator({ min: 1 }),
71-
]),
68+
override params = new ObjectValSan({
69+
schema: {
70+
itemId: new ComposedValSan([
71+
new StringToNumberValSan(),
72+
new MinValidator({ min: 1 }),
73+
]),
74+
},
7275
});
7376

7477
override async handle(
@@ -80,9 +83,11 @@ export class ValidationRouter extends BaseApiRouter {
8083
class TestBodyEndpoint extends PostEndpoint {
8184
override path = '/body';
8285

83-
override body = new ObjectSanitizer({
84-
name: new NameValSan(),
85-
email: new EmailValidator(),
86+
override body = new ObjectValSan({
87+
schema: {
88+
name: new NameValSan(),
89+
email: new EmailValidator(),
90+
},
8691
});
8792

8893
override async handle(
@@ -97,30 +102,38 @@ export class ValidationRouter extends BaseApiRouter {
97102
class TestAllValidationEndpoint extends PostEndpoint {
98103
override path = '/all/:userId';
99104

100-
override body = new ObjectSanitizer({
101-
name: new NameValSan(),
102-
email: new EmailValidator(),
105+
override body = new ObjectValSan({
106+
schema: {
107+
name: new NameValSan(),
108+
email: new EmailValidator(),
109+
},
103110
});
104111

105-
override query = new ObjectSanitizer({
106-
age: new ComposedValSan([
107-
new StringToNumberValSan(),
108-
new MinValidator({ min: 0 }),
109-
]),
112+
override query = new ObjectValSan({
113+
schema: {
114+
age: new ComposedValSan([
115+
new StringToNumberValSan(),
116+
new MinValidator({ min: 0 }),
117+
]),
118+
},
110119
});
111120

112-
override params = new ObjectSanitizer({
113-
userId: new ComposedValSan([
114-
new StringToNumberValSan(),
115-
new MinValidator({ min: 1 }),
116-
]),
121+
override params = new ObjectValSan({
122+
schema: {
123+
userId: new ComposedValSan([
124+
new StringToNumberValSan(),
125+
new MinValidator({ min: 1 }),
126+
]),
127+
},
117128
});
118129

119-
override headers = new ObjectSanitizer({
120-
'X-User-Token': new ComposedValSan([
121-
new TrimSanitizer(),
122-
new LengthValidator({ minLength: 10 }),
123-
]),
130+
override headers = new ObjectValSan({
131+
schema: {
132+
'X-User-Token': new ComposedValSan([
133+
new TrimSanitizer(),
134+
new LengthValidator({ minLength: 10 }),
135+
]),
136+
},
124137
});
125138

126139
async handle(request: ApiRequest) {
@@ -137,18 +150,20 @@ export class ValidationRouter extends BaseApiRouter {
137150
},
138151
class OptionalValidationEndpoint extends GetEndpoint {
139152
override path = '/optional-validation';
140-
override query = new ObjectSanitizer({
141-
name: new ComposedValSan(
142-
[
143-
new TrimSanitizer(),
144-
new LengthValidator({ minLength: 3 }),
145-
],
146-
{ isOptional: true }
147-
),
148-
email: new ComposedValSan(
149-
[new TrimSanitizer(), new EmailValidator()],
150-
{ isOptional: true }
151-
),
153+
override query = new ObjectValSan({
154+
schema: {
155+
name: new ComposedValSan(
156+
[
157+
new TrimSanitizer(),
158+
new LengthValidator({ minLength: 3 }),
159+
],
160+
{ isOptional: true }
161+
),
162+
email: new ComposedValSan(
163+
[new TrimSanitizer(), new EmailValidator()],
164+
{ isOptional: true }
165+
),
166+
},
152167
});
153168

154169
override async handle(

test/spec/openapi/oas-endpoint-component-converter-response.spec.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'jasmine';
22
// eslint-disable-next-line max-len
33
import { OasEndpointComponentConverter } from '../../../src/oas/oas-endpoint-component-converter';
4-
import { ObjectSanitizer, IntegerValidator, EmailValidator } from 'valsan';
4+
import { IntegerValidator, EmailValidator, ObjectValSan } from 'valsan';
55
import { GetEndpoint } from '../../../src/router/endpoints/get-endpoint';
66
import { PostEndpoint } from '../../../src/router/endpoints/post-endpoint';
77
import { ApiRequest, ApiResponse, ApiNextFunction } from '../../../src/router';
@@ -15,9 +15,11 @@ describe('OasEndpointComponentConverter - Response Schemas', () => {
1515

1616
it('generates response schema from response sanitizer', () => {
1717
class TestEndpoint extends GetEndpoint {
18-
override response = new ObjectSanitizer({
19-
id: new IntegerValidator(),
20-
email: new EmailValidator(),
18+
override response = new ObjectValSan({
19+
schema: {
20+
id: new IntegerValidator(),
21+
email: new EmailValidator(),
22+
},
2123
});
2224

2325
override responseExample = {
@@ -52,8 +54,10 @@ describe('OasEndpointComponentConverter - Response Schemas', () => {
5254

5355
it('includes response example in schema', () => {
5456
class TestEndpoint extends GetEndpoint {
55-
override response = new ObjectSanitizer({
56-
id: new IntegerValidator(),
57+
override response = new ObjectValSan({
58+
schema: {
59+
id: new IntegerValidator(),
60+
},
5761
});
5862

5963
override responseExample = {
@@ -108,16 +112,20 @@ describe('OasEndpointComponentConverter - Response Schemas', () => {
108112

109113
it('includes both body and response schemas', () => {
110114
class TestEndpoint extends PostEndpoint {
111-
override body = new ObjectSanitizer({
112-
name: new IntegerValidator(),
115+
override body = new ObjectValSan({
116+
schema: {
117+
name: new IntegerValidator(),
118+
},
113119
});
114120

115121
override bodyExample = {
116122
name: 'test',
117123
};
118124

119-
override response = new ObjectSanitizer({
120-
id: new IntegerValidator(),
125+
override response = new ObjectValSan({
126+
schema: {
127+
id: new IntegerValidator(),
128+
},
121129
});
122130

123131
override responseExample = {
@@ -148,10 +156,12 @@ describe('OasEndpointComponentConverter - Response Schemas', () => {
148156

149157
it('generates correct schema structure for complex ' + 'response', () => {
150158
class TestEndpoint extends GetEndpoint {
151-
override response = new ObjectSanitizer({
152-
id: new IntegerValidator(),
153-
email: new EmailValidator(),
154-
status: new IntegerValidator(),
159+
override response = new ObjectValSan({
160+
schema: {
161+
id: new IntegerValidator(),
162+
email: new EmailValidator(),
163+
status: new IntegerValidator(),
164+
},
155165
});
156166

157167
override responseExample = {

0 commit comments

Comments
 (0)