@nhtio/validation 1.20250911.1 → 1.20251028.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +13 -13
- package/index.cjs.map +1 -1
- package/index.d.ts +1 -1
- package/index.mjs +13 -13
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/private/core/root.d.ts +63 -0
- package/private/index.d.ts +14 -27
- package/private/patches/knex.d.ts +10 -0
- package/private/schemas/datetime.d.ts +1 -1
- package/private/schemas.d.ts +96 -1
package/package.json
CHANGED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modern ES6 + TypeScript reimplementation of Joi's root factory.
|
|
3
|
+
*
|
|
4
|
+
* Based on: https://github.com/hapijs/joi/blob/master/lib/index.js
|
|
5
|
+
*
|
|
6
|
+
* This module recreates Joi's internal root factory to enable deeper
|
|
7
|
+
* customization through schema type modifiers and shortcuts modifiers.
|
|
8
|
+
*/
|
|
9
|
+
import type { Root } from 'joi';
|
|
10
|
+
import type { Schema } from '../index';
|
|
11
|
+
export type SchemaTypeDefinition = Schema;
|
|
12
|
+
export type SchemaTypeDefinititionMiddlewareFn = (ctx: SchemaTypeDefinition, root: Root, args: any[]) => SchemaTypeDefinition;
|
|
13
|
+
export type ShortcutsMiddlewareFn = (ctx: string[]) => string[];
|
|
14
|
+
export interface RootFactoryOptions {
|
|
15
|
+
schemaTypeModifiers?: SchemaTypeDefinititionMiddlewareFn[];
|
|
16
|
+
shortcutsModifiers?: ShortcutsMiddlewareFn[];
|
|
17
|
+
}
|
|
18
|
+
export declare class RootFactory {
|
|
19
|
+
static readonly types: {
|
|
20
|
+
alternatives: any;
|
|
21
|
+
any: any;
|
|
22
|
+
array: any;
|
|
23
|
+
boolean: any;
|
|
24
|
+
date: any;
|
|
25
|
+
function: any;
|
|
26
|
+
link: any;
|
|
27
|
+
number: any;
|
|
28
|
+
object: any;
|
|
29
|
+
string: any;
|
|
30
|
+
symbol: any;
|
|
31
|
+
binary: any;
|
|
32
|
+
};
|
|
33
|
+
static readonly aliases: {
|
|
34
|
+
alt: string;
|
|
35
|
+
bool: string;
|
|
36
|
+
func: string;
|
|
37
|
+
};
|
|
38
|
+
static assertValue(value: any, schema: any, annotate: boolean, args: any[]): any;
|
|
39
|
+
static generate(root: any, schema: any, args: any[]): any;
|
|
40
|
+
static expandExtension(extension: any, joi: any): any[];
|
|
41
|
+
static getMethods(): {
|
|
42
|
+
ValidationError: any;
|
|
43
|
+
version: any;
|
|
44
|
+
cache: any;
|
|
45
|
+
assert(value: any, schema: any, ...args: any[]): void;
|
|
46
|
+
attempt(value: any, schema: any, ...args: any[]): any;
|
|
47
|
+
build(this: Root, desc: any): any;
|
|
48
|
+
checkPreferences(prefs: any): void;
|
|
49
|
+
compile(this: Root, schema: any, options: any): any;
|
|
50
|
+
defaults(this: Root, modifier: any): Root;
|
|
51
|
+
expression(...args: any[]): any;
|
|
52
|
+
extend(this: Root, ...extensions: any[]): Root;
|
|
53
|
+
isError: any;
|
|
54
|
+
isExpression: any;
|
|
55
|
+
isRef: any;
|
|
56
|
+
isSchema: any;
|
|
57
|
+
in(...args: any[]): any;
|
|
58
|
+
override: any;
|
|
59
|
+
ref(...args: any[]): any;
|
|
60
|
+
types(this: any): any;
|
|
61
|
+
};
|
|
62
|
+
static create(options?: RootFactoryOptions): Root;
|
|
63
|
+
}
|
package/private/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { default as Joi } from 'joi';
|
|
2
1
|
import type { DateTime } from 'luxon';
|
|
3
2
|
import type { PhoneSchema } from './schemas/phone';
|
|
4
3
|
import type { BigIntSchema } from './schemas/bigint';
|
|
5
4
|
import type { DatetimeSchema } from './schemas/datetime';
|
|
6
5
|
import type { CountryOrUnknown } from '@nhtio/phone-object';
|
|
7
|
-
import type { Root, Reference, SchemaMap, SchemaLike } from 'joi';
|
|
8
6
|
import type { I18nCallback, SetI18nCallback } from './patches/i18n';
|
|
7
|
+
import type { ValidationOptions, Root, Reference as JoiReference, SchemaMap, SchemaLike, WhenSchemaOptions, WhenOptions, State, ReferenceOptions } from 'joi';
|
|
9
8
|
import type { AnySchema, StringSchema, BinarySchema, NumberSchema, BooleanSchema, ObjectSchema, ArraySchema, DateSchema, AlternativesSchema, FunctionSchema, LinkSchema, SymbolSchema, Schema } from './schemas';
|
|
9
|
+
export type Reference = JoiReference & {
|
|
10
|
+
resolve: (value: any, state: State, prefs: ValidationOptions, local?: any, options?: ReferenceOptions) => any;
|
|
11
|
+
};
|
|
10
12
|
/**
|
|
11
13
|
* Extended Joi root interface that includes custom schema types for
|
|
12
14
|
* additional validation scenarios.
|
|
@@ -26,7 +28,7 @@ import type { AnySchema, StringSchema, BinarySchema, NumberSchema, BooleanSchema
|
|
|
26
28
|
*
|
|
27
29
|
* @public
|
|
28
30
|
*/
|
|
29
|
-
export interface ValidationRoot extends Omit<Root, 'allow' | 'alt' | 'alternatives' | 'any' | 'array' | 'binary' | 'bool' | 'boolean' | 'date' | 'disallow' | 'equal' | 'exist' | 'forbidden' | 'func' | 'function' | 'invalid' | 'link' | 'not' | 'number' | 'object' | 'optional' | 'preferences' | 'prefs' | 'required' | 'string' | 'symbol' | 'types' | 'valid' | 'when'> {
|
|
31
|
+
export interface ValidationRoot extends Omit<Root, 'allow' | 'alt' | 'alternatives' | 'any' | 'array' | 'binary' | 'bool' | 'boolean' | 'date' | 'disallow' | 'equal' | 'exist' | 'forbidden' | 'func' | 'function' | 'invalid' | 'link' | 'not' | 'number' | 'object' | 'optional' | 'preferences' | 'prefs' | 'required' | 'string' | 'symbol' | 'types' | 'valid' | 'when' | 'ref'> {
|
|
30
32
|
/**
|
|
31
33
|
* Generates a schema object that matches any data type.
|
|
32
34
|
*/
|
|
@@ -165,16 +167,20 @@ export interface ValidationRoot extends Omit<Root, 'allow' | 'alt' | 'alternativ
|
|
|
165
167
|
/**
|
|
166
168
|
* Overrides the global validate() options for the current key and any sub-key.
|
|
167
169
|
*/
|
|
168
|
-
preferences(options:
|
|
170
|
+
preferences(options: ValidationOptions): Schema;
|
|
169
171
|
/**
|
|
170
172
|
* Overrides the global validate() options for the current key and any sub-key.
|
|
171
173
|
*/
|
|
172
|
-
prefs(options:
|
|
174
|
+
prefs(options: ValidationOptions): Schema;
|
|
173
175
|
/**
|
|
174
176
|
* Converts the type into an alternatives type where the conditions are merged into the type definition where:
|
|
175
177
|
*/
|
|
176
|
-
when(ref: string | Reference, options:
|
|
177
|
-
when(ref: Schema, options:
|
|
178
|
+
when(ref: string | Reference, options: WhenOptions | WhenOptions[]): AlternativesSchema;
|
|
179
|
+
when(ref: Schema, options: WhenSchemaOptions): AlternativesSchema;
|
|
180
|
+
/**
|
|
181
|
+
* Creates a reference to another schema key.
|
|
182
|
+
*/
|
|
183
|
+
ref(key: string, options?: ReferenceOptions): Reference;
|
|
178
184
|
/**
|
|
179
185
|
* Sets a global internationalization callback that applies to all validator instances.
|
|
180
186
|
*
|
|
@@ -232,27 +238,8 @@ export interface ValidationRoot extends Omit<Root, 'allow' | 'alt' | 'alternativ
|
|
|
232
238
|
$clearI18n: () => ValidationRoot;
|
|
233
239
|
$i18n: I18nCallback;
|
|
234
240
|
}
|
|
235
|
-
/**
|
|
236
|
-
* Extended Joi instance with custom schema types.
|
|
237
|
-
*
|
|
238
|
-
* This instance includes all standard Joi functionality plus additional
|
|
239
|
-
* schema types for additional validation scenarios.
|
|
240
|
-
*
|
|
241
|
-
* @example
|
|
242
|
-
* ```typescript
|
|
243
|
-
* import { validator } from '@nhtio/validation'
|
|
244
|
-
*
|
|
245
|
-
* // Standard Joi usage
|
|
246
|
-
* const userSchema = validator.object({
|
|
247
|
-
* name: validator.string().required(),
|
|
248
|
-
* age: validator.number().min(0),
|
|
249
|
-
* balance: validator.bigint().positive() // Custom BigInt type
|
|
250
|
-
* })
|
|
251
|
-
* ```
|
|
252
|
-
*
|
|
253
|
-
* @public
|
|
254
|
-
*/
|
|
255
241
|
export declare const validator: ValidationRoot;
|
|
256
242
|
export type { BigIntSchema, DatetimeSchema, PhoneSchema, SetI18nCallback, I18nCallback };
|
|
257
243
|
export type * from './schemas';
|
|
258
244
|
export { encode, decode } from './utils';
|
|
245
|
+
export type { Knex } from 'knex';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SchemaTypeDefinititionMiddlewareFn } from '../core/root';
|
|
2
|
+
export declare const knexMessages: {
|
|
3
|
+
'knex.unique': string;
|
|
4
|
+
'knex.exists': string;
|
|
5
|
+
'knex.missingConnection': string;
|
|
6
|
+
'knex.invalidTable': string;
|
|
7
|
+
'knex.invalidColumn': string;
|
|
8
|
+
'knex.internal': string;
|
|
9
|
+
};
|
|
10
|
+
export declare const knex: SchemaTypeDefinititionMiddlewareFn;
|
package/private/schemas.d.ts
CHANGED
|
@@ -1,9 +1,40 @@
|
|
|
1
|
+
import type { Knex } from 'knex';
|
|
2
|
+
import type { Reference } from '..';
|
|
1
3
|
import type { DateTime } from 'luxon';
|
|
2
4
|
import type { PhoneSchema } from './schemas/phone';
|
|
3
5
|
import type { BigIntSchema } from './schemas/bigint';
|
|
4
6
|
import type { DatetimeSchema } from './schemas/datetime';
|
|
5
|
-
import type {
|
|
7
|
+
import type { QueryClientContract } from '@adonisjs/lucid/types/database';
|
|
8
|
+
import type { DatabaseQueryBuilderContract } from '@adonisjs/lucid/types/querybuilder';
|
|
9
|
+
import type { default as Joi, AnySchema as JoiAnySchema, BasicType, CustomHelpers, ExternalHelpers } from 'joi';
|
|
10
|
+
export type { Knex, QueryClientContract, DatabaseQueryBuilderContract };
|
|
11
|
+
export type KnexTransaction = Knex.Transaction;
|
|
12
|
+
export type KnexQueryBuilder = Knex.QueryBuilder;
|
|
13
|
+
export type QueryClient = Knex | KnexTransaction | QueryClientContract;
|
|
14
|
+
export type QueryBuilder = KnexQueryBuilder | DatabaseQueryBuilderContract;
|
|
15
|
+
export interface KnexConnectionConfigurations {
|
|
16
|
+
client: NonNullable<Knex.Config['client']>;
|
|
17
|
+
connection: NonNullable<Knex.Config['connection']>;
|
|
18
|
+
[key: string | number | symbol]: any;
|
|
19
|
+
}
|
|
20
|
+
export type KnexSchemaConnection = QueryClient | KnexConnectionConfigurations;
|
|
6
21
|
export type DefaultableValue = Reference | BasicType | DateTime | bigint | ((parent: any, helpers: CustomHelpers) => Reference | BasicType | DateTime | bigint);
|
|
22
|
+
/**
|
|
23
|
+
* Options for database-backed validation helpers such as `uniqueInDb` and `existsInDb`.
|
|
24
|
+
*/
|
|
25
|
+
export interface DbValidationOptions {
|
|
26
|
+
/**
|
|
27
|
+
* Perform case-insensitive comparisons when querying the database.
|
|
28
|
+
* Defaults to `false`.
|
|
29
|
+
*/
|
|
30
|
+
caseInsensitive?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Optional function that receives the Knex query builder (or equivalent) so
|
|
33
|
+
* the caller can append additional WHERE clauses (or joins). Can be async.
|
|
34
|
+
* Example: `async (query, value, column, helpers) => query.where('tenant_id', tenantId)`
|
|
35
|
+
*/
|
|
36
|
+
filter?: (queryBuilder: QueryBuilder, value: any, column: string, helpers: Omit<ExternalHelpers, 'warn' | 'error' | 'message'>) => void | Promise<void>;
|
|
37
|
+
}
|
|
7
38
|
/**
|
|
8
39
|
* Base schema type for all validation schemas.
|
|
9
40
|
*
|
|
@@ -100,6 +131,70 @@ export interface AnySchema<TSchema = any> extends Omit<JoiAnySchema<TSchema>, '$
|
|
|
100
131
|
warning(code: string, context: Joi.Context): this;
|
|
101
132
|
when(ref: string | Reference, options: Joi.WhenOptions | Joi.WhenOptions[]): this;
|
|
102
133
|
when(ref: Schema, options: Joi.WhenSchemaOptions): this;
|
|
134
|
+
$_knex: KnexSchemaConnection | undefined;
|
|
135
|
+
/**
|
|
136
|
+
* Sets the database connection for database validation rules.
|
|
137
|
+
* This must be called before using `.uniqueInDb()` or `.existsInDb()`.
|
|
138
|
+
*
|
|
139
|
+
* @param connection - A Knex instance, transaction, or connection configuration
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* import knex from 'knex'
|
|
144
|
+
* const db = knex({ client: 'pg', connection: {...} })
|
|
145
|
+
* const schema = joi.string().knex(db).uniqueInDb('users', 'email')
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
knex(connection: KnexSchemaConnection): this;
|
|
149
|
+
/**
|
|
150
|
+
* Alias for `.knex()`. Sets the database connection for database validation rules.
|
|
151
|
+
*
|
|
152
|
+
* @param connection - A Knex instance, transaction, or connection configuration
|
|
153
|
+
*/
|
|
154
|
+
db(connection: KnexSchemaConnection): this;
|
|
155
|
+
/**
|
|
156
|
+
* Validates that the value is unique in the specified database table and column.
|
|
157
|
+
* Requires `.knex()` or `.db()` to be called first to set the database connection.
|
|
158
|
+
*
|
|
159
|
+
* @param table - The database table name (can be a Joi reference)
|
|
160
|
+
* @param column - The column name to check (can be a Joi reference)
|
|
161
|
+
* @param options - Optional configuration:
|
|
162
|
+
* - `caseInsensitive`: Perform case-insensitive comparison (default: false)
|
|
163
|
+
* - `filter`: Async function to add additional WHERE clauses to the query
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```typescript
|
|
167
|
+
* const schema = joi.object({
|
|
168
|
+
* email: joi.string().email().knex(db).uniqueInDb('users', 'email'),
|
|
169
|
+
* username: joi.string().knex(db).uniqueInDb('users', 'username', {
|
|
170
|
+
* caseInsensitive: true,
|
|
171
|
+
* filter: async (query) => query.where('tenant_id', tenantId)
|
|
172
|
+
* })
|
|
173
|
+
* })
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
uniqueInDb(table: string | Reference, column: string | Reference, options?: DbValidationOptions): this;
|
|
177
|
+
/**
|
|
178
|
+
* Validates that the value exists in the specified database table and column.
|
|
179
|
+
* Requires `.knex()` or `.db()` to be called first to set the database connection.
|
|
180
|
+
*
|
|
181
|
+
* @param table - The database table name (can be a Joi reference)
|
|
182
|
+
* @param column - The column name to check (can be a Joi reference)
|
|
183
|
+
* @param options - Optional configuration:
|
|
184
|
+
* - `caseInsensitive`: Perform case-insensitive comparison (default: false)
|
|
185
|
+
* - `filter`: Async function to add additional WHERE clauses to the query
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* const schema = joi.object({
|
|
190
|
+
* country_id: joi.number().knex(db).existsInDb('countries', 'id'),
|
|
191
|
+
* category: joi.string().knex(db).existsInDb('categories', 'name', {
|
|
192
|
+
* caseInsensitive: true
|
|
193
|
+
* })
|
|
194
|
+
* })
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
existsInDb(table: string | Reference, column: string | Reference, options?: DbValidationOptions): this;
|
|
103
198
|
/**
|
|
104
199
|
* Sets a default value if the original value is `undefined`.
|
|
105
200
|
*
|