@nhtio/validation 0.1.0-master-d7a77552 → 0.1.0-master-649f9ed8
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 +96200 -96721
- package/index.cjs.map +1 -1
- package/index.d.ts +1 -1
- package/index.mjs +96205 -96698
- package/index.mjs.map +1 -1
- package/package.json +1 -4
- package/private/core/root.d.ts +63 -0
- package/private/index.d.ts +15 -35
- package/private/patches/i18n.d.ts +0 -3
- package/private/patches/index.d.ts +1 -2
- package/private/patches/knex.d.ts +15 -1
- package/private/schemas.d.ts +96 -6
- package/private/utils.d.ts +82 -2
- package/private/monkeypatches/index.d.ts +0 -2
- package/private/monkeypatches/validate_async.d.ts +0 -23
- package/private/root.d.ts +0 -17
- package/private/schemas/knex.d.ts +0 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nhtio/validation",
|
|
3
|
-
"version": "0.1.0-master-
|
|
3
|
+
"version": "0.1.0-master-649f9ed8",
|
|
4
4
|
"description": "A powerful schema description language and data validator",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "Jak Giveon <jak@nht.io>",
|
|
@@ -25,9 +25,6 @@
|
|
|
25
25
|
"sqlite3"
|
|
26
26
|
]
|
|
27
27
|
},
|
|
28
|
-
"peerDependencies": {
|
|
29
|
-
"@adonisjs/lucid": "^21.8.0"
|
|
30
|
-
},
|
|
31
28
|
"packageManager": "pnpm@10.8.0+sha512.0e82714d1b5b43c74610193cb20734897c1d00de89d0e18420aebc5977fa13d780a9cb05734624e81ebd81cc876cd464794850641c48b9544326b5622ca29971",
|
|
32
29
|
"type": "module",
|
|
33
30
|
"dependencies": {}
|
|
@@ -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,13 +1,14 @@
|
|
|
1
|
-
import type * 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';
|
|
9
|
-
import type {
|
|
7
|
+
import type { ValidationOptions, Root, Reference as JoiReference, SchemaMap, SchemaLike, WhenSchemaOptions, WhenOptions, State, ReferenceOptions } from 'joi';
|
|
10
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
|
+
};
|
|
11
12
|
/**
|
|
12
13
|
* Extended Joi root interface that includes custom schema types for
|
|
13
14
|
* additional validation scenarios.
|
|
@@ -27,7 +28,7 @@ import type { AnySchema, StringSchema, BinarySchema, NumberSchema, BooleanSchema
|
|
|
27
28
|
*
|
|
28
29
|
* @public
|
|
29
30
|
*/
|
|
30
|
-
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'> {
|
|
31
32
|
/**
|
|
32
33
|
* Generates a schema object that matches any data type.
|
|
33
34
|
*/
|
|
@@ -110,11 +111,6 @@ export interface ValidationRoot extends Omit<Root, 'allow' | 'alt' | 'alternativ
|
|
|
110
111
|
* @param country - Optional country code or reference for phone validation
|
|
111
112
|
*/
|
|
112
113
|
phone<TSchema = string>(country?: CountryOrUnknown | Reference | null): PhoneSchema<TSchema>;
|
|
113
|
-
/**
|
|
114
|
-
* Generates a schema object that matches a database record using a Knex.js connection or Adonis Lucid Database connection for validation.
|
|
115
|
-
* @param connection - The database connection or QueryClientContract to use for validation
|
|
116
|
-
*/
|
|
117
|
-
knex<TSchema = any>(connection: KnexSchemaConnection): KnexSchema<TSchema>;
|
|
118
114
|
/**
|
|
119
115
|
* Returns an object where each key is a plain joi schema type.
|
|
120
116
|
* Useful for creating type shortcuts using deconstruction.
|
|
@@ -136,7 +132,6 @@ export interface ValidationRoot extends Omit<Root, 'allow' | 'alt' | 'alternativ
|
|
|
136
132
|
bigint: BigIntSchema;
|
|
137
133
|
datetime: DatetimeSchema;
|
|
138
134
|
phone: PhoneSchema;
|
|
139
|
-
knex: KnexSchema;
|
|
140
135
|
};
|
|
141
136
|
/**
|
|
142
137
|
* Whitelists a value
|
|
@@ -172,16 +167,20 @@ export interface ValidationRoot extends Omit<Root, 'allow' | 'alt' | 'alternativ
|
|
|
172
167
|
/**
|
|
173
168
|
* Overrides the global validate() options for the current key and any sub-key.
|
|
174
169
|
*/
|
|
175
|
-
preferences(options:
|
|
170
|
+
preferences(options: ValidationOptions): Schema;
|
|
176
171
|
/**
|
|
177
172
|
* Overrides the global validate() options for the current key and any sub-key.
|
|
178
173
|
*/
|
|
179
|
-
prefs(options:
|
|
174
|
+
prefs(options: ValidationOptions): Schema;
|
|
180
175
|
/**
|
|
181
176
|
* Converts the type into an alternatives type where the conditions are merged into the type definition where:
|
|
182
177
|
*/
|
|
183
|
-
when(ref: string | Reference, options:
|
|
184
|
-
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;
|
|
185
184
|
/**
|
|
186
185
|
* Sets a global internationalization callback that applies to all validator instances.
|
|
187
186
|
*
|
|
@@ -239,27 +238,8 @@ export interface ValidationRoot extends Omit<Root, 'allow' | 'alt' | 'alternativ
|
|
|
239
238
|
$clearI18n: () => ValidationRoot;
|
|
240
239
|
$i18n: I18nCallback;
|
|
241
240
|
}
|
|
242
|
-
/**
|
|
243
|
-
* Extended Joi instance with custom schema types.
|
|
244
|
-
*
|
|
245
|
-
* This instance includes all standard Joi functionality plus additional
|
|
246
|
-
* schema types for additional validation scenarios.
|
|
247
|
-
*
|
|
248
|
-
* @example
|
|
249
|
-
* ```typescript
|
|
250
|
-
* import { validator } from '@nhtio/validation'
|
|
251
|
-
*
|
|
252
|
-
* // Standard Joi usage
|
|
253
|
-
* const userSchema = validator.object({
|
|
254
|
-
* name: validator.string().required(),
|
|
255
|
-
* age: validator.number().min(0),
|
|
256
|
-
* balance: validator.bigint().positive() // Custom BigInt type
|
|
257
|
-
* })
|
|
258
|
-
* ```
|
|
259
|
-
*
|
|
260
|
-
* @public
|
|
261
|
-
*/
|
|
262
241
|
export declare const validator: ValidationRoot;
|
|
263
|
-
export type { BigIntSchema, DatetimeSchema, PhoneSchema,
|
|
242
|
+
export type { BigIntSchema, DatetimeSchema, PhoneSchema, SetI18nCallback, I18nCallback };
|
|
264
243
|
export type * from './schemas';
|
|
265
244
|
export { encode, decode } from './utils';
|
|
245
|
+
export type { Knex } from 'knex';
|
|
@@ -1,2 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Knex } from 'knex';
|
|
2
|
+
import type { SchemaTypeDefinititionMiddlewareFn } from '../core/root';
|
|
3
|
+
import type { KnexSchemaConnection } from '../schemas';
|
|
4
|
+
export declare const knexMessages: {
|
|
5
|
+
'knex.unique': string;
|
|
6
|
+
'knex.exists': string;
|
|
7
|
+
'knex.missingConnection': string;
|
|
8
|
+
'knex.invalidTable': string;
|
|
9
|
+
'knex.invalidColumn': string;
|
|
10
|
+
'knex.internal': string;
|
|
11
|
+
};
|
|
12
|
+
export declare const resolveQueryBuilder: (connection: KnexSchemaConnection, table: string) => {
|
|
13
|
+
client: Knex;
|
|
14
|
+
query: Knex.QueryBuilder;
|
|
15
|
+
};
|
|
2
16
|
export declare const knex: SchemaTypeDefinititionMiddlewareFn;
|
package/private/schemas.d.ts
CHANGED
|
@@ -1,10 +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 {
|
|
6
|
-
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;
|
|
7
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
|
+
}
|
|
8
38
|
/**
|
|
9
39
|
* Base schema type for all validation schemas.
|
|
10
40
|
*
|
|
@@ -101,6 +131,70 @@ export interface AnySchema<TSchema = any> extends Omit<JoiAnySchema<TSchema>, '$
|
|
|
101
131
|
warning(code: string, context: Joi.Context): this;
|
|
102
132
|
when(ref: string | Reference, options: Joi.WhenOptions | Joi.WhenOptions[]): this;
|
|
103
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;
|
|
104
198
|
/**
|
|
105
199
|
* Sets a default value if the original value is `undefined`.
|
|
106
200
|
*
|
|
@@ -119,10 +213,6 @@ export interface AnySchema<TSchema = any> extends Omit<JoiAnySchema<TSchema>, '$
|
|
|
119
213
|
*/
|
|
120
214
|
default(value?: DefaultableValue): this;
|
|
121
215
|
cast(to: 'map' | 'number' | 'set' | 'string' | 'object'): this;
|
|
122
|
-
/**
|
|
123
|
-
* Add the Knex.js extension methods to a string schema.
|
|
124
|
-
*/
|
|
125
|
-
knex(connection: KnexSchemaConnection): KnexSchema<TSchema>;
|
|
126
216
|
}
|
|
127
217
|
/**
|
|
128
218
|
* Schema type for string validation.
|
package/private/utils.d.ts
CHANGED
|
@@ -1,4 +1,71 @@
|
|
|
1
1
|
import type { Schema } from './schemas';
|
|
2
|
+
/**
|
|
3
|
+
* Options for encoding and decoding validation schemas.
|
|
4
|
+
*
|
|
5
|
+
* These options control what gets serialized when encoding schemas and how
|
|
6
|
+
* they're reconstructed during decoding. The defaults prioritize security
|
|
7
|
+
* and are designed for the most common use case: sharing validation rules
|
|
8
|
+
* between frontend and backend environments.
|
|
9
|
+
*/
|
|
10
|
+
export type EncoderOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* Include database connections and database validation rules in the encoded schema.
|
|
13
|
+
*
|
|
14
|
+
* When `false` (default):
|
|
15
|
+
* - Database connections (`.knex()`, `.db()`) are stripped from the encoded schema
|
|
16
|
+
* - Database validation rules (`.uniqueInDb()`, `.existsInDb()`) are converted to no-ops
|
|
17
|
+
* - Filter functions in database rules are replaced with empty functions
|
|
18
|
+
* - This prevents credential leakage and reduces payload size
|
|
19
|
+
*
|
|
20
|
+
* When `true`:
|
|
21
|
+
* - Database connection configurations are serialized (if they're plain objects)
|
|
22
|
+
* - Database validation rules and their filter functions are preserved
|
|
23
|
+
* - **Security warning**: Only use this in trusted backend-to-backend communication
|
|
24
|
+
* - Encoded schemas will require re-attaching database connections after decoding
|
|
25
|
+
*
|
|
26
|
+
* **Why this defaults to `false`:**
|
|
27
|
+
* 1. **Security**: Prevents accidental exposure of database credentials in client-side code
|
|
28
|
+
* 2. **Use case alignment**: Frontend validation typically doesn't need database rules
|
|
29
|
+
* 3. **Credential safety**: Database connections often contain sensitive connection strings
|
|
30
|
+
* 4. **Function security**: Custom filter functions may contain business logic or credentials
|
|
31
|
+
*
|
|
32
|
+
* @default false
|
|
33
|
+
*
|
|
34
|
+
* @example Frontend/Backend Schema Sharing (default)
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Backend
|
|
37
|
+
* const schema = joi.object({
|
|
38
|
+
* email: joi.string().email().uniqueInDb('users', 'email')
|
|
39
|
+
* }).knex(db)
|
|
40
|
+
*
|
|
41
|
+
* const encoded = encode(schema) // withDatabase defaults to false
|
|
42
|
+
* // Database rules are stripped, safe to send to frontend
|
|
43
|
+
*
|
|
44
|
+
* // Frontend receives and decodes
|
|
45
|
+
* const frontendSchema = decode(encoded)
|
|
46
|
+
* // Only gets email format validation, no database checks
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @example Backend-to-Backend Schema Transfer
|
|
50
|
+
* ```typescript
|
|
51
|
+
* // Service A
|
|
52
|
+
* const schema = joi.object({
|
|
53
|
+
* username: joi.string().uniqueInDb('users', 'username', {
|
|
54
|
+
* filter: async (query) => query.where('tenant_id', tenantId)
|
|
55
|
+
* })
|
|
56
|
+
* }).knex({ client: 'pg', connection: { host: 'localhost', ... } })
|
|
57
|
+
*
|
|
58
|
+
* const encoded = encode(schema, { withDatabase: true })
|
|
59
|
+
* // Sends to trusted Service B
|
|
60
|
+
*
|
|
61
|
+
* // Service B
|
|
62
|
+
* const decoded = decode(encoded, { withDatabase: true })
|
|
63
|
+
* const rehydrated = decoded.knex(serviceB_db_connection)
|
|
64
|
+
* // Now has full database validation capabilities
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
withDatabase?: boolean;
|
|
68
|
+
};
|
|
2
69
|
/**
|
|
3
70
|
* Encodes a validation schema into a compressed, base64-encoded string for transport between environments.
|
|
4
71
|
*
|
|
@@ -46,7 +113,7 @@ import type { Schema } from './schemas';
|
|
|
46
113
|
*
|
|
47
114
|
* @see {@link decode} For decoding schemas from encoded strings
|
|
48
115
|
*/
|
|
49
|
-
export declare const encode: (schema: Schema) => string;
|
|
116
|
+
export declare const encode: (schema: Schema, options?: EncoderOptions) => string;
|
|
50
117
|
/**
|
|
51
118
|
* Decodes a base64-encoded schema string back into a usable validation schema.
|
|
52
119
|
*
|
|
@@ -63,6 +130,7 @@ export declare const encode: (schema: Schema) => string;
|
|
|
63
130
|
* - Schema reconstruction using Joi's build method
|
|
64
131
|
*
|
|
65
132
|
* @param base64 - The base64-encoded schema string
|
|
133
|
+
* @param options - Decoding options
|
|
66
134
|
* @returns A reconstructed validation schema ready for validation
|
|
67
135
|
* @throws {TypeError} When the encoded string is not a valid schema
|
|
68
136
|
* @throws {TypeError} When the schema version is invalid or incompatible
|
|
@@ -101,6 +169,18 @@ export declare const encode: (schema: Schema) => string;
|
|
|
101
169
|
* const schema = decode(oldSchema) // Works - backward compatible
|
|
102
170
|
* ```
|
|
103
171
|
*
|
|
172
|
+
* @security
|
|
173
|
+
* **IMPORTANT: Only decode schemas from trusted sources.**
|
|
174
|
+
*
|
|
175
|
+
* Decoded schemas may contain serialized functions that are evaluated using the
|
|
176
|
+
* Function constructor. Never decode schemas from:
|
|
177
|
+
* - User input or user-controlled data
|
|
178
|
+
* - Untrusted third-party APIs
|
|
179
|
+
* - Any source you do not control
|
|
180
|
+
*
|
|
181
|
+
* If the schema source is not under your direct control, validate its integrity
|
|
182
|
+
* using cryptographic signatures or checksums before decoding.
|
|
183
|
+
*
|
|
104
184
|
* @see {@link encode} For encoding schemas into transportable strings
|
|
105
185
|
*/
|
|
106
|
-
export declare const decode: (base64: string) => Schema;
|
|
186
|
+
export declare const decode: (base64: string, options?: EncoderOptions) => Schema;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { Schema } from '../';
|
|
2
|
-
import type { AsyncValidationOptions, ValidationWarning, Context } from 'joi';
|
|
3
|
-
export declare const doValidation: (value: any, schema: any, state: any, prefs: any, overrides?: any) => Promise<any>;
|
|
4
|
-
export declare const validateAsync: <TOpts extends AsyncValidationOptions, TSchema = any>(this: Schema, value: any, options?: TOpts) => Promise<TOpts extends {
|
|
5
|
-
artifacts: true;
|
|
6
|
-
} | {
|
|
7
|
-
warnings: true;
|
|
8
|
-
} ? {
|
|
9
|
-
value: TSchema;
|
|
10
|
-
} & (TOpts extends {
|
|
11
|
-
artifacts: true;
|
|
12
|
-
} ? {
|
|
13
|
-
artifacts: Map<any, string[][]>;
|
|
14
|
-
} : {}) & (TOpts extends {
|
|
15
|
-
warnings: true;
|
|
16
|
-
} ? {
|
|
17
|
-
warning: ValidationWarning;
|
|
18
|
-
} : {}) : TSchema>;
|
|
19
|
-
export declare const doAsyncValidateForKeysSchema: (value: any, { schema, error, state, prefs }: Context) => Promise<{
|
|
20
|
-
value: any;
|
|
21
|
-
errors: any;
|
|
22
|
-
} | undefined>;
|
|
23
|
-
export declare const doAsyncValidationForAlternativesSchema: (value: any, helpers: Context) => Promise<any>;
|
package/private/root.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* In order to create a better DX, and to allow for deeper
|
|
3
|
-
* patching of root instances of Joi, we are going to completely
|
|
4
|
-
* recreate the Joi default export here based on:
|
|
5
|
-
* https://github.com/hapijs/joi/blob/master/lib/index.js
|
|
6
|
-
* Due to the lack of type definitions for the internal parts of Joi,
|
|
7
|
-
* this file will be mainly untyped.
|
|
8
|
-
*/
|
|
9
|
-
import type { Schema } from '../index';
|
|
10
|
-
export type SchemaTypeDefinition = Schema;
|
|
11
|
-
export type SchemaTypeDefinititionMiddlewareFn = (ctx: SchemaTypeDefinition) => SchemaTypeDefinition;
|
|
12
|
-
export type ShortcutsMiddlewareFn = (ctx: string[]) => string[];
|
|
13
|
-
export type RootFactoryOptions = {
|
|
14
|
-
schemaTypeModifiers?: SchemaTypeDefinititionMiddlewareFn[];
|
|
15
|
-
shortcutsModifiers?: ShortcutsMiddlewareFn[];
|
|
16
|
-
};
|
|
17
|
-
export declare const internals: any;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { Knex } from 'knex';
|
|
2
|
-
import type { AnySchema } from '../../index';
|
|
3
|
-
import type { QueryClientContract } from '@adonisjs/lucid/types/database';
|
|
4
|
-
import type { ExtensionFactory, Reference } from 'joi';
|
|
5
|
-
import type { DatabaseQueryBuilderContract } from '@adonisjs/lucid/types/querybuilder';
|
|
6
|
-
export type QueryClient = Knex | Knex.Transaction | QueryClientContract;
|
|
7
|
-
export type QueryBuilder = Knex.QueryBuilder | DatabaseQueryBuilderContract;
|
|
8
|
-
export interface KnexConnectionConfigurations {
|
|
9
|
-
client: NonNullable<Knex.Config['client']>;
|
|
10
|
-
connection: NonNullable<Knex.Config['connection']>;
|
|
11
|
-
[key: string | number | symbol]: any;
|
|
12
|
-
}
|
|
13
|
-
export type KnexSchemaConnection = QueryClient | KnexConnectionConfigurations;
|
|
14
|
-
export type KnexSchemaSearchRuleOptions = {
|
|
15
|
-
caseInsensitive: boolean;
|
|
16
|
-
filter: (queryBuilder: QueryBuilder, value: any, column: string) => void | Promise<void>;
|
|
17
|
-
};
|
|
18
|
-
export type KnexSchemaSearchRule<TSchema = any> = (table: string | Reference, column: string | Reference, options?: Partial<KnexSchemaSearchRuleOptions>) => KnexSchema<TSchema>;
|
|
19
|
-
export interface KnexSchema<TSchema = any> extends Omit<AnySchema<TSchema>, 'cast'> {
|
|
20
|
-
unique: KnexSchemaSearchRule<TSchema>;
|
|
21
|
-
exists: KnexSchemaSearchRule<TSchema>;
|
|
22
|
-
db: (connection: KnexSchemaConnection) => KnexSchema<TSchema>;
|
|
23
|
-
}
|
|
24
|
-
export declare const messages: {
|
|
25
|
-
'knex.unique': string;
|
|
26
|
-
'knex.exists': string;
|
|
27
|
-
'knex.missingConnection': string;
|
|
28
|
-
'knex.invalidTable': string;
|
|
29
|
-
'knex.invalidColumn': string;
|
|
30
|
-
'knex.internal': string;
|
|
31
|
-
};
|
|
32
|
-
export declare const knex: ExtensionFactory;
|