Skip to content

Commit 47595e6

Browse files
committed
Don't import Joi typings
1 parent 200a5af commit 47595e6

12 files changed

+167
-67
lines changed

API.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2712,7 +2712,7 @@ Registers a server validation module used to compile raw validation rules into v
27122712

27132713
- `validator` - the validation module (e.g. **joi**).
27142714

2715-
Return value: none.
2715+
Return value: The `server` object.
27162716

27172717
Note: the validator is only used when validation rules are not pre-compiled schemas. When a validation rules is a function or schema object, the rule is used as-is and the validator is not used. When setting a validator inside a plugin, the validator is only applied to routes set up by the plugin and plugins registered by it.
27182718

lib/config.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,10 @@ internals.routeBase = Validate.object({
229229
failAction: internals.failAction,
230230
errorFields: Validate.object(),
231231
options: Validate.object().default(),
232-
validator: Validate.object()
232+
validator: Validate.object({
233+
compile: Validate.function().required()
234+
})
235+
.unknown()
233236
})
234237
.default()
235238
});

lib/core.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ const Request = require('./request');
2626
const Response = require('./response');
2727
const Route = require('./route');
2828
const Toolkit = require('./toolkit');
29-
const Validation = require('./validation');
3029

3130

3231
const internals = {
@@ -128,7 +127,7 @@ exports = module.exports = internals.Core = class {
128127
this._initializeCache();
129128

130129
if (this.settings.routes.validate.validator) {
131-
this.validator = Validation.validator(this.settings.routes.validate.validator);
130+
this.validator = this.settings.routes.validate.validator;
132131
}
133132

134133
this.listener = this._createListener();

lib/route.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ internals.config = function (chain) {
455455

456456
let config = chain[0];
457457
for (const item of chain) {
458-
config = Hoek.applyToDefaults(config, item, { shallow: ['bind', 'validate.headers', 'validate.payload', 'validate.params', 'validate.query', 'validate.state'] });
458+
config = Hoek.applyToDefaults(config, item, { shallow: ['bind', 'validate.headers', 'validate.payload', 'validate.params', 'validate.query', 'validate.state', 'validate.validator'] });
459459
}
460460

461461
return config;

lib/server.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -560,9 +560,12 @@ internals.Server = class {
560560

561561
validator(validator) {
562562

563+
Hoek.assert(typeof validator?.compile === 'function', 'Validator must have a compile() method');
563564
Hoek.assert(!this.realm.validator, 'Validator already set');
564565

565-
this.realm.validator = Validation.validator(validator);
566+
this.realm.validator = validator;
567+
568+
return this;
566569
}
567570

568571
start() {

lib/types/route.d.ts

+41-32
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11

2-
import { ObjectSchema, ValidationOptions, SchemaMap, Schema } from 'joi';
3-
42
import { PluginSpecificConfiguration} from './plugin';
53
import { MergeType, ReqRef, ReqRefDefaults, MergeRefs, AuthMode } from './request';
6-
import { ContentDecoders, ContentEncoders, RouteRequestExtType, RouteExtObject, Server } from './server';
4+
import { ContentDecoders, ContentEncoders, RouteRequestExtType, RouteExtObject, Server, Validation } from './server';
75
import { Lifecycle, Json, HTTP_METHODS } from './utils';
86

97
/**
@@ -363,26 +361,24 @@ export interface RouteOptionsPreObject<Refs extends ReqRef = ReqRefDefaults> {
363361
failAction?: Lifecycle.FailAction | undefined;
364362
}
365363

366-
export type ValidationObject = SchemaMap;
367-
368364
/**
369365
* * true - any query parameter value allowed (no validation performed). false - no parameter value allowed.
370366
* * a joi validation object.
371367
* * a validation function using the signature async function(value, options) where:
372368
* * * value - the request.* object containing the request parameters.
373369
* * * options - options.
374370
*/
375-
export type RouteOptionsResponseSchema =
376-
boolean
377-
| ValidationObject
378-
| Schema
379-
| ((value: object | Buffer | string, options: ValidationOptions) => Promise<any>);
371+
export type RouteOptionsSchema<V extends Validation.Compiler | null, T extends Validation.ValidatedReqProperties | null> =
372+
boolean
373+
| Validation.ExtractedSchema<V>
374+
| Validation.Validator
375+
| Validation.DirectValidator<T>;
380376

381377
/**
382378
* Processing rules for the outgoing response.
383379
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsresponse)
384380
*/
385-
export interface RouteOptionsResponse {
381+
export interface RouteOptionsResponse<V extends Validation.Compiler | null> {
386382
/**
387383
* @default 204.
388384
* The default HTTP status code when the payload is considered empty. Value can be 200 or 204. Note that a 200 status code is converted to a 204 only at the time of response transmission (the
@@ -411,7 +407,7 @@ export interface RouteOptionsResponse {
411407
* custom validation function is defined via schema or status then options can an arbitrary object that will be passed to this function as the second argument.
412408
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsresponseoptions)
413409
*/
414-
options?: ValidationOptions | undefined; // TODO needs validation
410+
options?: Validation.ExtractedOptions<V> | undefined;
415411

416412
/**
417413
* @default true.
@@ -440,15 +436,15 @@ export interface RouteOptionsResponse {
440436
* output.payload. If an error is thrown, the error is processed according to failAction.
441437
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsresponseschema)
442438
*/
443-
schema?: RouteOptionsResponseSchema | undefined;
439+
schema?: RouteOptionsSchema<V, null> | undefined;
444440

445441
/**
446442
* @default none.
447443
* Validation schemas for specific HTTP status codes. Responses (excluding errors) not matching the listed status codes are validated using the default schema.
448444
* status is set to an object where each key is a 3 digit HTTP status code and the value has the same definition as schema.
449445
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsresponsestatus)
450446
*/
451-
status?: Record<string, RouteOptionsResponseSchema> | undefined;
447+
status?: Record<string, RouteOptionsSchema<V, null>> | undefined;
452448

453449
/**
454450
* The default HTTP status code used to set a response error when the request is closed or aborted before the
@@ -558,7 +554,7 @@ export type RouteOptionsSecure = boolean | RouteOptionsSecureObject;
558554
* Request input validation rules for various request components.
559555
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsvalidate)
560556
*/
561-
export interface RouteOptionsValidate {
557+
export interface RouteOptionsValidate<V extends Validation.Compiler | null> {
562558
/**
563559
* @default none.
564560
* An optional object with error fields copied into every validation error response.
@@ -580,7 +576,7 @@ export interface RouteOptionsValidate {
580576
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsvalidateheaders)
581577
* @default true
582578
*/
583-
headers?: RouteOptionsResponseSchema | undefined;
579+
headers?: RouteOptionsSchema<V, 'headers'> | undefined;
584580

585581
/**
586582
* An options object passed to the joi rules or the custom validation methods. Used for setting global options such as stripUnknown or abortEarly (the complete list is available here).
@@ -593,7 +589,7 @@ export interface RouteOptionsValidate {
593589
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsvalidateparams)
594590
* @default true
595591
*/
596-
options?: ValidationOptions | object | undefined;
592+
options?: Validation.ExtractedOptions<V> | undefined;
597593

598594
/**
599595
* Validation rules for incoming request path parameters, after matching the path against the route, extracting any parameters, and storing them in request.params, where:
@@ -607,7 +603,7 @@ export interface RouteOptionsValidate {
607603
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsvalidateparams)
608604
* @default true
609605
*/
610-
params?: RouteOptionsResponseSchema | undefined;
606+
params?: RouteOptionsSchema<V, 'params'> | undefined;
611607

612608
/**
613609
* Validation rules for incoming request payload (request body), where:
@@ -617,7 +613,7 @@ export interface RouteOptionsValidate {
617613
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsvalidatepayload)
618614
* @default true
619615
*/
620-
payload?: RouteOptionsResponseSchema | undefined;
616+
payload?: RouteOptionsSchema<V, 'payload'> | undefined;
621617

622618
/**
623619
* Validation rules for incoming request URI query component (the key-value part of the URI between '?' and '#'). The query is parsed into its individual key-value pairs, decoded, and stored in
@@ -628,17 +624,23 @@ export interface RouteOptionsValidate {
628624
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsvalidatequery)
629625
* @default true
630626
*/
631-
query?: RouteOptionsResponseSchema | undefined;
627+
query?: RouteOptionsSchema<V, 'query'> | undefined;
632628

633629
/**
634630
* Validation rules for incoming cookies.
635631
* The cookie header is parsed and decoded into the request.state prior to validation.
636632
* @default true
637633
*/
638-
state?: RouteOptionsResponseSchema | undefined;
634+
state?: RouteOptionsSchema<V, 'state'> | undefined;
635+
636+
/**
637+
* Sets a server validation module used to compile raw validation rules into validation schemas (e.g. **joi**).
638+
* @default null
639+
*/
640+
validator?: V | null;
639641
}
640642

641-
export interface CommonRouteProperties<Refs extends ReqRef = ReqRefDefaults> {
643+
export interface CommonRouteProperties<Refs extends ReqRef = ReqRefDefaults, V extends Validation.Compiler | null = null> {
642644
/**
643645
* Application-specific route configuration state. Should not be used by plugins which should use options.plugins[name] instead.
644646
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsapp)
@@ -812,7 +814,7 @@ export interface CommonRouteProperties<Refs extends ReqRef = ReqRefDefaults> {
812814
* Processing rules for the outgoing response.
813815
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsresponse)
814816
*/
815-
response?: RouteOptionsResponse | undefined;
817+
response?: RouteOptionsResponse<V> | undefined;
816818

817819
/**
818820
* @default false (security headers disabled).
@@ -864,7 +866,7 @@ export interface CommonRouteProperties<Refs extends ReqRef = ReqRefDefaults> {
864866
* Request input validation rules for various request components.
865867
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-routeoptionsvalidate)
866868
*/
867-
validate?: RouteOptionsValidate | undefined;
869+
validate?: RouteOptionsValidate<V> | undefined;
868870
}
869871

870872
export interface AccessScopes {
@@ -884,15 +886,15 @@ export interface AuthSettings {
884886
access?: AccessSetting[] | undefined;
885887
}
886888

887-
export interface RouteSettings<Refs extends ReqRef = ReqRefDefaults> extends CommonRouteProperties<Refs> {
889+
export interface RouteSettings<Refs extends ReqRef = ReqRefDefaults, V extends Validation.Compiler | null = null> extends CommonRouteProperties<Refs, V> {
888890
auth?: AuthSettings | undefined;
889891
}
890892

891893
/**
892894
* Each route can be customized to change the default behavior of the request lifecycle.
893895
* For context [See docs](https://github.com/hapijs/hapi/blob/master/API.md#route-options)
894896
*/
895-
export interface RouteOptions<Refs extends ReqRef = ReqRefDefaults> extends CommonRouteProperties<Refs> {
897+
export interface RouteOptions<Refs extends ReqRef = ReqRefDefaults, V extends Validation.Compiler | null = null> extends CommonRouteProperties<Refs, V> {
896898
/**
897899
* Route authentication configuration. Value can be:
898900
* false to disable authentication if a default strategy is set.
@@ -913,10 +915,17 @@ export interface RulesInfo {
913915
vhost: string;
914916
}
915917

916-
export interface RulesOptions<Refs extends ReqRef = ReqRefDefaults> {
917-
validate: {
918-
schema?: ObjectSchema<MergeRefs<Refs>['Rules']> | Record<keyof MergeRefs<Refs>['Rules'], Schema> | undefined;
919-
options?: ValidationOptions | undefined;
918+
export interface JoiLikeSchema {
919+
validate(value: unknown, options: Record<string, any>): { value: any } | { error: any };
920+
}
921+
922+
export interface RulesOptions<V extends Validation.Compiler | null> {
923+
validate: V extends null ? {
924+
schema: JoiLikeSchema;
925+
options?: Record<string, any> | undefined;
926+
} : {
927+
schema: Validation.ExtractedSchema<V>;
928+
options?: Validation.ExtractedOptions<V> | undefined;
920929
};
921930
}
922931

@@ -941,7 +950,7 @@ type RouteDefMethods = Exclude<HTTP_METHODS | Lowercase<HTTP_METHODS>, 'HEAD' |
941950
* * rules - route custom rules object. The object is passed to each rules processor registered with server.rules(). Cannot be used if route.options.rules is defined.
942951
* For context [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-serverrouteroute)
943952
*/
944-
export interface ServerRoute<Refs extends ReqRef = ReqRefDefaults> {
953+
export interface ServerRoute<Refs extends ReqRef = ReqRefDefaults, V extends Validation.Compiler | null = null> {
945954
/**
946955
* (required) the absolute path used to match incoming requests (must begin with '/'). Incoming requests are compared to the configured paths based on the server's router configuration. The path
947956
* can include named parameters enclosed in {} which will be matched against literal values in the request as described in Path parameters. For context [See
@@ -971,7 +980,7 @@ export interface ServerRoute<Refs extends ReqRef = ReqRefDefaults> {
971980
* additional route options. The options value can be an object or a function that returns an object using the signature function(server) where server is the server the route is being added to
972981
* and this is bound to the current realm's bind option.
973982
*/
974-
options?: RouteOptions<Refs> | ((server: Server) => RouteOptions<Refs>) | undefined;
983+
options?: RouteOptions<Refs, V> | ((server: Server<ServerApplicationState, V>) => RouteOptions<Refs, V>) | undefined;
975984

976985
/**
977986
* route custom rules object. The object is passed to each rules processor registered with server.rules(). Cannot be used if route.options.rules is defined.

lib/types/server/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ export * from './methods';
99
export * from './options';
1010
export * from './server';
1111
export * from './state';
12+
export * from './validation';

lib/types/server/options.d.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import * as https from 'https';
44
import { MimosOptions } from '@hapi/mimos';
55

66
import { PluginSpecificConfiguration } from '../plugin';
7+
import { ReqRefDefaults } from '../request';
78
import { RouteOptions } from '../route';
89
import { CacheProvider, ServerOptionsCache } from './cache';
910
import { SameSitePolicy } from './state';
11+
import { Validation } from './validation';
1012

1113
export interface ServerOptionsCompression {
1214
minBytes: number;
@@ -25,7 +27,7 @@ export interface ServerOptionsApp {
2527
* All options are optionals.
2628
* [See docs](https://github.com/hapijs/hapi/blob/master/API.md#-server-options)
2729
*/
28-
export interface ServerOptions {
30+
export interface ServerOptions<V extends Validation.Compiler | null> {
2931
/**
3032
* @default '0.0.0.0' (all available network interfaces).
3133
* Sets the hostname or IP address the server will listen on. If not configured, defaults to host if present, otherwise to all available network interfaces. Set to '127.0.0.1' or 'localhost' to
@@ -194,7 +196,7 @@ export interface ServerOptions {
194196
* @default none.
195197
* A route options object used as the default configuration for every route.
196198
*/
197-
routes?: RouteOptions | undefined;
199+
routes?: RouteOptions<ReqRefDefaults, V> | undefined;
198200

199201
/**
200202
* Default value:

0 commit comments

Comments
 (0)