نعم هو منشئ المخططات لتحليل قيمة وقت التشغيل والتحقق من صحتها. قم بتعريف مخطط، أو تحويل قيمة لمطابقتها، أو تأكيد شكل قيمة موجودة، أو كليهما. مخطط نعم معبر للغاية ويسمح بنمذجة عمليات التحقق المعقدة والمترابطة أو تحويل القيمة.
أنت تعرض الآن مستندات الإصدار v1.0.0 من yup، وتتوفر مستندات ما قبل الإصدار 1: هنا
ميزات القاتل :
يتكون المخطط من إجراءات التحليل (التحويلات) بالإضافة إلى التأكيدات (الاختبارات) حول قيمة الإدخال. التحقق من صحة قيمة الإدخال لتحليلها وتشغيل مجموعة التأكيدات المكونة. ربط الأساليب معًا لبناء المخطط.
import { object , string , number , date , InferType } from 'yup' ;
let userSchema = object ( {
name : string ( ) . required ( ) ,
age : number ( ) . required ( ) . positive ( ) . integer ( ) ,
email : string ( ) . email ( ) ,
website : string ( ) . url ( ) . nullable ( ) ,
createdOn : date ( ) . default ( ( ) => new Date ( ) ) ,
} ) ;
// parse and assert validity
let user = await userSchema . validate ( await fetchUser ( ) ) ;
type User = InferType < typeof userSchema > ;
/* {
name: string;
age: number;
email?: string | undefined
website?: string | null | undefined
createdOn: Date
}*/
استخدم مخططًا لإجبار أو "إرسال" قيمة إدخال إلى النوع الصحيح، وقم بتحويل هذه القيمة بشكل اختياري إلى قيم أكثر تحديدًا وتحديدًا، دون إجراء المزيد من التأكيدات.
// Attempts to coerce values to the correct type
let parsedUser = userSchema . cast ( {
name : 'jimmy' ,
age : '24' ,
createdOn : '2014-09-23T19:25:25Z' ,
} ) ;
// ✅ { name: 'jimmy', age: 24, createdOn: Date }
هل تعلم أن قيمة الإدخال الخاصة بك قد تم تحليلها بالفعل؟ يمكنك التحقق من صحة الإدخال "بشكل صارم"، وتجنب العبء الزائد لتشغيل منطق التحليل.
// ValidationError "age is not a number"
let parsedUser = await userSchema . validate (
{
name : 'jimmy' ,
age : '24' ,
} ,
{ strict : true } ,
) ;
yup
reach(schema: Schema, path: string, value?: object, context?: object): Schema
addMethod(schemaType: Schema, name: string, method: ()=> Schema): void
ref(path: string, options: { contextPrefix: string }): Ref
lazy((value: any) => Schema): Lazy
ValidationError(errors: string | Array<string>, value: any, path: string)
Schema
Schema.clone(): Schema
Schema.label(label: string): Schema
Schema.meta(metadata: SchemaMetadata): Schema
Schema.describe(options?: ResolveOptions): SchemaDescription
Schema.concat(schema: Schema): Schema
Schema.validate(value: any, options?: object): Promise<InferType<Schema>, ValidationError>
Schema.validateSync(value: any, options?: object): InferType<Schema>
Schema.validateAt(path: string, value: any, options?: object): Promise<InferType<Schema>, ValidationError>
Schema.validateSyncAt(path: string, value: any, options?: object): InferType<Schema>
Schema.isValid(value: any, options?: object): Promise<boolean>
Schema.isValidSync(value: any, options?: object): boolean
Schema.cast(value: any, options = {}): InferType<Schema>
Schema.isType(value: any): value is InferType<Schema>
Schema.strict(enabled: boolean = false): Schema
Schema.strip(enabled: boolean = true): Schema
Schema.withMutation(builder: (current: Schema) => void): void
Schema.default(value: any): Schema
Schema.getDefault(options?: object): Any
Schema.nullable(message?: string | function): Schema
Schema.nonNullable(message?: string | function): Schema
Schema.defined(): Schema
Schema.optional(): Schema
Schema.required(message?: string | function): Schema
Schema.notRequired(): Schema
Schema.typeError(message: string): Schema
Schema.oneOf(arrayOfValues: Array<any>, message?: string | function): Schema
: equals
Schema.notOneOf(arrayOfValues: Array<any>, message?: string | function)
Schema.when(keys: string | string[], builder: object | (values: any[], schema) => Schema): Schema
Schema.test(name: string, message: string | function | any, test: function): Schema
Schema.test(options: object): Schema
Schema.transform((currentValue: any, originalValue: any) => any): Schema
string.required(message?: string | function): Schema
string.length(limit: number | Ref, message?: string | function): Schema
string.min(limit: number | Ref, message?: string | function): Schema
string.max(limit: number | Ref, message?: string | function): Schema
string.matches(regex: Regex, message?: string | function): Schema
string.matches(regex: Regex, options: { message: string, excludeEmptyString: bool }): Schema
string.email(message?: string | function): Schema
string.url(message?: string | function): Schema
string.uuid(message?: string | function): Schema
string.datetime(options?: {message?: string | function, allowOffset?: boolean, precision?: number})
string.datetime(message?: string | function)
string.ensure(): Schema
string.trim(message?: string | function): Schema
string.lowercase(message?: string | function): Schema
string.uppercase(message?: string | function): Schema
number.min(limit: number | Ref, message?: string | function): Schema
number.max(limit: number | Ref, message?: string | function): Schema
number.lessThan(max: number | Ref, message?: string | function): Schema
number.moreThan(min: number | Ref, message?: string | function): Schema
number.positive(message?: string | function): Schema
number.negative(message?: string | function): Schema
number.integer(message?: string | function): Schema
number.truncate(): Schema
number.round(type: 'floor' | 'ceil' | 'trunc' | 'round' = 'round'): Schema
date.min(limit: Date | string | Ref, message?: string | function): Schema
date.max(limit: Date | string | Ref, message?: string | function): Schema
array.of(type: Schema): this
array.json(): this
array.length(length: number | Ref, message?: string | function): this
array.min(limit: number | Ref, message?: string | function): this
array.max(limit: number | Ref, message?: string | function): this
array.ensure(): this
array.compact(rejector: (value) => boolean): Schema
object.shape(fields: object, noSortEdges?: Array<[string, string]>): Schema
object.json(): this
object.concat(schemaB: ObjectSchema): ObjectSchema
object.pick(keys: string[]): Schema
object.omit(keys: string[]): Schema
object.from(fromKey: string, toKey: string, alias: boolean = false): this
object.noUnknown(onlyKnownKeys: boolean = true, message?: string | function): Schema
object.camelCase(): Schema
object.constantCase(): Schema
تتكون تعريفات المخطط من "التحويلات" التحليلية التي تعالج المدخلات إلى الشكل والنوع المطلوب، و"الاختبارات" التي تقدم تأكيدات على البيانات التي تم تحليلها. يقوم المخطط أيضًا بتخزين مجموعة من "البيانات التعريفية"، وهي تفاصيل حول المخطط نفسه، والتي يمكن استخدامها لتحسين رسائل الخطأ، أو إنشاء أدوات تستهلك المخطط ديناميكيًا، أو إجراء تسلسل للمخطط في تنسيق آخر.
من أجل تحقيق أقصى قدر من المرونة، يسمح نعم بتشغيل كل من التحليل والتأكيدات بشكل منفصل لتتناسب مع الاحتياجات المحددة
يقوم كل نوع مدمج بتنفيذ تحليل النوع الأساسي، والذي يكون مفيدًا عند تحليل البيانات المتسلسلة، مثل JSON. بالإضافة إلى ذلك، تنفذ الأنواع تحويلات محددة يمكن تمكينها.
let num = number ( ) . cast ( '1' ) ; // 1
let obj = object ( {
firstName : string ( ) . lowercase ( ) . trim ( ) ,
} )
. json ( )
. camelCase ( )
. cast ( '{"first_name": "jAnE "}' ) ; // { firstName: 'jane' }
يمكن إضافة تحويلات مخصصة
let reversedString = string ( )
. transform ( ( currentValue ) => currentValue . split ( '' ) . reverse ( ) . join ( '' ) )
. cast ( 'dlrow olleh' ) ; // "hello world"
تشكل التحويلات "خط أنابيب"، حيث يتم نقل قيمة التحويل السابق إلى التحويل التالي. عندما تكون قيمة الإدخال undefined
، سيتم تطبيق المخطط الافتراضي إذا تم تكوينه.
احترس! لا يتم ضمان أن تكون القيم أنواعًا صالحة في وظائف التحويل. ربما تكون التحويلات السابقة قد فشلت. على سبيل المثال، قد يتلقى تحويل الرقم قيمة الإدخال
NaN
أو رقمًا.
نعم يقوم المخطط بتشغيل "اختبارات" على قيم الإدخال. تؤكد الاختبارات أن المدخلات تتوافق مع بعض المعايير. تختلف الاختبارات عن التحويلات، حيث أنها لا تغير أو تغير المدخلات (أو نوعها) وعادة ما تكون مخصصة لعمليات التحقق التي يصعب، إن لم يكن من المستحيل، تمثيلها في الأنواع الثابتة.
string ( )
. min ( 3 , 'must be at least 3 characters long' )
. email ( 'must be a valid email' )
. validate ( 'no' ) ; // ValidationError
كما هو الحال مع التحويلات، يمكن تخصيص الاختبارات بسرعة
let jamesSchema = string ( ) . test (
'is-james' ,
( d ) => ` ${ d . path } is not James` ,
( value ) => value == null || value === 'James' ,
) ;
jamesSchema . validateSync ( 'James' ) ; // "James"
jamesSchema . validateSync ( 'Jane' ) ; // ValidationError "this is not James"
تنبيه: على عكس التحويلات، يتم ضمان أن تكون
value
في الاختبار المخصص من النوع الصحيح (في هذه الحالة سلسلة اختيارية). لا يزال من الممكن أن يكونundefined
أوnull
اعتمادًا على مخططك في تلك الحالات، قد ترغب في إرجاعtrue
للقيم الغائبة ما لم يقدم التحويل تأكيدات متعلقة بالتواجد. سيقوم خيار الاختبارskipAbsent
بذلك نيابةً عنك إذا تم تعيينه.
في أبسط الحالات، تُرجع دالة الاختبار true
أو false
اعتمادًا على ما إذا كان الشيك قد تم اجتيازه. في حالة فشل الاختبار، نعم سوف يلقي ValidationError
مع رسالتك (أو الرسالة الافتراضية) لهذا الاختبار. يحتوي ValidationErrors أيضًا على مجموعة من البيانات الوصفية الأخرى حول الاختبار، بما في ذلك اسمه، والوسيطات (إن وجدت) التي تم استدعاؤها بها، والمسار إلى الحقل الفاشل في حالة التحقق من الصحة المتداخل.
يمكن أيضًا إنشاء رسائل خطأ أثناء التنقل لتخصيص كيفية فشل المخطط.
let order = object ( {
no : number ( ) . required ( ) ,
sku : string ( ) . test ( {
name : 'is-sku' ,
skipAbsent : true ,
test ( value , ctx ) {
if ( ! value . startsWith ( 's-' ) ) {
return ctx . createError ( { message : 'SKU missing correct prefix' } )
}
if ( ! value . endsWith ( '-42a' ) ) {
return ctx . createError ( { message : 'SKU missing correct suffix' } )
}
if ( value . length < 10 ) {
return ctx . createError ( { message : 'SKU is not the right length' } )
}
return true
}
} )
} )
order . validate ( { no : 1234 , sku : 's-1a45-14a' } )
المخططات غير قابلة للتغيير، حيث يقوم كل استدعاء أسلوب بإرجاع كائن مخطط جديد. قم بإعادة استخدامها وتمريرها دون خوف من تغيير مثيل آخر.
let optionalString = string ( ) . optional ( ) ;
let definedString = optionalString . defined ( ) ;
let value = undefined ;
optionalString . isValid ( value ) ; // true
definedString . isValid ( value ) ; // false
مخطط نعم ينتج واجهات TypeScript ثابتة. استخدم InferType
لاستخراج تلك الواجهة:
import * as yup from 'yup' ;
let personSchema = yup . object ( {
firstName : yup . string ( ) . defined ( ) ,
nickName : yup . string ( ) . default ( '' ) . nullable ( ) ,
sex : yup
. mixed ( )
. oneOf ( [ 'male' , 'female' , 'other' ] as const )
. defined ( ) ,
email : yup . string ( ) . nullable ( ) . email ( ) ,
birthDate : yup . date ( ) . nullable ( ) . min ( new Date ( 1900 , 0 , 1 ) ) ,
} ) ;
interface Person extends yup . InferType < typeof personSchema > {
// using interface instead of type generally gives nicer editor feedback
}
يتم استخدام الإعداد الافتراضي للمخطط عندما ينتج عن الإرسال قيمة إخراج undefined
. ولهذا السبب، يؤثر تعيين الإعداد الافتراضي على نوع مخرجات المخطط، مما يؤدي بشكل أساسي إلى تمييزه على أنه "محدد ().
import { string } from 'yup' ;
let value : string = string ( ) . default ( 'hi' ) . validate ( undefined ) ;
// vs
let value : string | undefined = string ( ) . validate ( undefined ) ;
في بعض الحالات، يوجد نوع TypeScript بالفعل، وتريد التأكد من أن مخططك ينتج نوعًا متوافقًا:
import { object , number , string , ObjectSchema } from 'yup' ;
interface Person {
name : string ;
age ?: number ;
sex : 'male' | 'female' | 'other' | null ;
}
// will raise a compile-time type error if the schema does not produce a valid Person
let schema : ObjectSchema < Person > = object ( {
name : string ( ) . defined ( ) ,
age : number ( ) . optional ( ) ,
sex : string < 'male' | 'female' | 'other' > ( ) . nullable ( ) . defined ( ) ,
} ) ;
// errors:
// "Type 'number | undefined' is not assignable to type 'string'."
let badSchema : ObjectSchema < Person > = object ( {
name : number ( ) ,
} ) ;
يمكنك استخدام سلوك دمج واجهة TypeScript لتوسيع أنواع المخططات إذا لزم الأمر. يجب أن توضع امتدادات النوع في ملف تعريف النوع "المحيط" مثل globals.d.ts
. تذكر أن تقوم بالفعل بتوسيع نوع yup في رمز التطبيق الخاص بك!
احترس! لا يعمل الدمج إلا إذا كان تعريف النوع هو نفسه تمامًا ، بما في ذلك الأدوية العامة. راجع كود مصدر نعم لكل نوع للتأكد من أنك تحدده بشكل صحيح
// globals.d.ts
declare module 'yup' {
interface StringSchema < TType , TContext , TDefault , TFlags > {
append ( appendStr : string ) : this ;
}
}
// app.ts
import { addMethod , string } from 'yup' ;
addMethod ( string , 'append' , function append ( appendStr : string ) {
return this . transform ( ( value ) => ` ${ value } ${ appendStr } ` ) ;
} ) ;
string ( ) . append ( '~~~~' ) . cast ( 'hi' ) ; // 'hi~~~~'
يجب أن يكون لديك خيار برنامج التحويل البرمجي strictNullChecks
ممكّنًا حتى يعمل استنتاج النوع.
نوصي أيضًا بإعدادات strictFunctionTypes
على false
للحصول على أنواع أفضل وظيفيًا. نعم، هذا يقلل من السلامة العامة، ولكن TypeScript يقوم بالفعل بتعطيل هذا التحقق من الأساليب والمنشئات (ملاحظة من مستندات TS):
أثناء تطوير هذه الميزة، اكتشفنا عددًا كبيرًا من التسلسلات الهرمية للفئات غير الآمنة بطبيعتها، بما في ذلك بعضها في DOM. ولهذا السبب، ينطبق الإعداد فقط على الوظائف المكتوبة في بناء جملة الدالة، وليس على تلك الموجودة في بناء جملة الطريقة:
ستختلف المسافة المقطوعة، لكننا وجدنا أن هذا الفحص لا يمنع العديد من الأخطاء الحقيقية، مع زيادة مقدار الإرسال الصريح المرهق في التطبيقات.
يمكن تخصيص رسائل الخطأ الافتراضية عندما لا يتم توفير أي رسالة مع اختبار التحقق من الصحة. إذا كانت هناك أية رسالة مفقودة في القاموس المخصص، فستكون رسالة الخطأ هي رسالة Yup الافتراضية.
import { setLocale } from 'yup' ;
setLocale ( {
mixed : {
default : 'Não é válido' ,
} ,
number : {
min : 'Deve ser maior que ${min}' ,
} ,
} ) ;
// now use Yup schemas AFTER you defined your custom dictionary
let schema = yup . object ( ) . shape ( {
name : yup . string ( ) ,
age : yup . number ( ) . min ( 18 ) ,
} ) ;
try {
await schema . validate ( { name : 'jimmy' , age : 11 } ) ;
} catch ( err ) {
err . name ; // => 'ValidationError'
err . errors ; // => ['Deve ser maior que 18']
}
إذا كنت بحاجة إلى دعم متعدد اللغات، نعم فقد قمت بتغطيتك. تقبل الدالة setLocale
الوظائف التي يمكن استخدامها لإنشاء كائنات خطأ باستخدام مفاتيح الترجمة والقيم. يمكن إدخالها في مكتبة i18n المفضلة لديك.
import { setLocale } from 'yup' ;
setLocale ( {
// use constant translation keys for messages without values
mixed : {
default : 'field_invalid' ,
} ,
// use functions to generate an error object that includes the value from the schema
number : {
min : ( { min } ) => ( { key : 'field_too_short' , values : { min } } ) ,
max : ( { max } ) => ( { key : 'field_too_big' , values : { max } } ) ,
} ,
} ) ;
// ...
let schema = yup . object ( ) . shape ( {
name : yup . string ( ) ,
age : yup . number ( ) . min ( 18 ) ,
} ) ;
try {
await schema . validate ( { name : 'jimmy' , age : 11 } ) ;
} catch ( err ) {
messages = err . errors . map ( ( err ) => i18next . t ( err . key ) ) ;
}
yup
تصدير الوحدة.
// core schema
import {
mixed ,
string ,
number ,
boolean ,
bool ,
date ,
object ,
array ,
ref ,
lazy ,
} from 'yup' ;
// Classes
import {
Schema ,
MixedSchema ,
StringSchema ,
NumberSchema ,
BooleanSchema ,
DateSchema ,
ArraySchema ,
ObjectSchema ,
} from 'yup' ;
// Types
import type { InferType , ISchema , AnySchema , AnyObjectSchema } from 'yup' ;
reach(schema: Schema, path: string, value?: object, context?: object): Schema
بالنسبة للمخططات المتداخلة، سوف يقوم reach
باسترداد مخطط داخلي بناءً على المسار المقدم.
بالنسبة للمخططات المتداخلة التي تحتاج إلى حل ديناميكيًا، يمكنك توفير value
وكائن context
بشكل اختياري.
import { reach } from 'yup' ;
let schema = object ( {
nested : object ( {
arr : array ( object ( { num : number ( ) . max ( 4 ) } ) ) ,
} ) ,
} ) ;
reach ( schema , 'nested.arr.num' ) ;
reach ( schema , 'nested.arr[].num' ) ;
reach ( schema , 'nested.arr[1].num' ) ;
reach ( schema , 'nested["arr"][1].num' ) ;
addMethod(schemaType: Schema, name: string, method: ()=> Schema): void
يضيف طريقة جديدة إلى أنواع المخططات الأساسية. أسلوب ملائم أكثر لـ schemaType.prototype[name] = method
.
import { addMethod , date } from 'yup' ;
addMethod ( date , 'format' , function format ( formats , parseStrict ) {
return this . transform ( ( value , originalValue , ctx ) => {
if ( ctx . isType ( value ) ) return value ;
value = Moment ( originalValue , formats , parseStrict ) ;
return value . isValid ( ) ? value . toDate ( ) : new Date ( '' ) ;
} ) ;
} ) ;
إذا كنت تريد إضافة طريقة إلى جميع أنواع المخططات، فقم بتوسيع الفئة الأساسية المجردة: Schema
import { addMethod , Schema } from 'yup' ;
addMethod ( Schema , 'myMethod' , ... )
ref(path: string, options: { contextPrefix: string }): Ref
ينشئ مرجعًا إلى حقل تابع أو فرعي آخر. يتم حل المراجع في وقت التحقق/الإرسال ويتم دعمها عند تحديدها. يتم تقييم المراجع بالترتيب الصحيح بحيث يتم حل قيمة المرجع قبل الحقل باستخدام المرجع (كن حذرًا من التبعيات الدائرية!).
import { ref , object , string } from 'yup' ;
let schema = object ( {
baz : ref ( 'foo.bar' ) ,
foo : object ( {
bar : string ( ) ,
} ) ,
x : ref ( '$x' ) ,
} ) ;
schema . cast ( { foo : { bar : 'boom' } } , { context : { x : 5 } } ) ;
// => { baz: 'boom', x: 5, foo: { bar: 'boom' } }
lazy((value: any) => Schema): Lazy
ينشئ مخططًا يتم تقييمه في وقت التحقق/الإرسال. مفيد لإنشاء مخطط عودي مثل الأشجار، للحقول والمصفوفات متعددة الأشكال.
حذر! عند تحديد مخطط كائن متكرر بين الوالدين والطفل، فأنت تريد إعادة تعيين default()
إلى null
على الطفل - وإلا فإن الكائن سوف يتداخل بشكل لا نهائي عند إرساله!
let node = object ( {
id : number ( ) ,
child : yup . lazy ( ( ) => node . default ( undefined ) ) ,
} ) ;
let renderable = yup . lazy ( ( value ) => {
switch ( typeof value ) {
case 'number' :
return number ( ) ;
case 'string' :
return string ( ) ;
default :
return mixed ( ) ;
}
} ) ;
let renderables = array ( ) . of ( renderable ) ;
ValidationError(errors: string | Array<string>, value: any, path: string)
ألقيت على عمليات التحقق من الصحة الفاشلة، مع الخصائص التالية
name
: "خطأ في التحقق"type
: نوع الاختبار المحدد أو "اسم" الاختبار الذي فشل.value
: قيمة الحقل الذي تم اختباره؛params
?: مدخلات الاختبار، مثل القيمة القصوى، والتعبير العادي، وما إلى ذلك؛path
: سلسلة تشير إلى مكان الخطأ. path
فارغ على مستوى الجذر.errors
: مجموعة من رسائل الخطأinner
: في حالة الأخطاء المجمعة، الداخلي عبارة عن مصفوفة من ValidationErrors
التي تم طرحها مسبقًا في سلسلة التحقق من الصحة. عندما يكون الخيار abortEarly
false
فهذا هو المكان الذي يمكنك فيه فحص كل خطأ يتم طرحه، وبدلاً من ذلك، ستحتوي errors
على جميع الرسائل من كل خطأ داخلي.Schema
Schema
هو الفئة الأساسية المجردة التي ترث منها جميع أنواع المخططات. ويوفر عددًا من الأساليب والخصائص الأساسية لجميع أنواع المخططات الأخرى.
ملاحظة: ما لم تكن تقوم بإنشاء نوع مخطط مخصص، فلا ينبغي أبدًا استخدام المخطط بشكل مباشر. بالنسبة إلى أنواع غير معروفة/أي أنواع، استخدم
mixed()
Schema.clone(): Schema
ينشئ نسخة عميقة من المخطط. يتم استخدام الاستنساخ داخليًا لإرجاع مخطط جديد مع كل تغيير في حالة المخطط.
Schema.label(label: string): Schema
يتجاوز اسم المفتاح المستخدم في رسائل الخطأ.
Schema.meta(metadata: SchemaMetadata): Schema
يُضاف إلى كائن بيانات التعريف، وهو مفيد لتخزين البيانات باستخدام مخطط، ولا ينتمي إلى كائن الإرسال نفسه.
يمكن تعريف واجهة SchemaMetadata
المخصصة من خلال الدمج مع واجهة CustomSchemaMetadata
. ابدأ بإنشاء ملف yup.d.ts
في الحزمة الخاصة بك وإنشاء واجهة CustomSchemaMetadata
المطلوبة:
// yup.d.ts
import 'yup' ;
declare module 'yup' {
// Define your desired `SchemaMetadata` interface by merging the
// `CustomSchemaMetadata` interface.
export interface CustomSchemaMetadata {
placeholderText ?: string ;
tooltipText ?: string ;
// …
}
}
Schema.describe(options?: ResolveOptions): SchemaDescription
يجمع تفاصيل المخطط (مثل التعريف والتسميات والاختبارات النشطة) في كائن وصف قابل للتسلسل.
let schema = object ( {
name : string ( ) . required ( ) ,
} ) ;
let description = schema . describe ( ) ;
بالنسبة للمخطط الذي يحتوي على مكونات ديناميكية (المراجع أو البطيئة أو الشروط)، يتطلب الوصف مزيدًا من السياق لإرجاع وصف المخطط بدقة. في هذه الحالات توفير options
import { ref , object , string , boolean } from 'yup' ;
let schema = object ( {
isBig : boolean ( ) ,
count : number ( ) . when ( 'isBig' , {
is : true ,
then : ( schema ) => schema . min ( 5 ) ,
otherwise : ( schema ) => schema . min ( 0 ) ,
} ) ,
} ) ;
schema . describe ( { value : { isBig : true } } ) ;
وفيما يلي أنواع الوصف، والتي تختلف قليلاً حسب نوع المخطط.
interface SchemaDescription {
type : string ;
label ?: string ;
meta : object | undefined ;
oneOf : unknown [ ] ;
notOneOf : unknown [ ] ;
default ?: unknown ;
nullable : boolean ;
optional : boolean ;
tests : Array < { name ?: string ; params : ExtraParams | undefined } > ;
// Present on object schema descriptions
fields : Record < string , SchemaFieldDescription > ;
// Present on array schema descriptions
innerType ?: SchemaFieldDescription ;
}
type SchemaFieldDescription =
| SchemaDescription
| SchemaRefDescription
| SchemaLazyDescription ;
interface SchemaRefDescription {
type : 'ref' ;
key : string ;
}
interface SchemaLazyDescription {
type : string ;
label ?: string ;
meta : object | undefined ;
}
Schema.concat(schema: Schema): Schema
إنشاء مثيل جديد للمخطط من خلال الجمع بين مخططين. يمكن ربط المخططات من نفس النوع فقط. concat
ليست وظيفة "دمج" بمعنى أن جميع الإعدادات من المخطط المقدم، تتجاوز الإعدادات الموجودة في القاعدة، بما في ذلك النوع والوجود والعدمية.
mixed < string > ( ) . defined ( ) . concat ( mixed < number > ( ) . nullable ( ) ) ;
// produces the equivalent to:
mixed < number > ( ) . defined ( ) . nullable ( ) ;
Schema.validate(value: any, options?: object): Promise<InferType<Schema>, ValidationError>
تقوم بإرجاع التحليلات والتحقق من صحة قيمة الإدخال، أو إرجاع القيمة التي تم تحليلها أو إلقاء خطأ. هذه الطريقة غير متزامنة وتُرجع كائن Promise، الذي تم استيفاؤه بالقيمة، أو رفضه باستخدام ValidationError
.
value = await schema . validate ( { name : 'jimmy' , age : 24 } ) ;
قم بتوفير options
للتحكم بشكل أكثر تحديدًا في سلوك التحقق من validate
.
interface Options {
// when true, parsing is skipped and the input is validated "as-is"
strict: boolean = false ;
// Throw on the first error or collect and return all
abortEarly: boolean = true ;
// Remove unspecified keys from objects
stripUnknown: boolean = false ;
// when `false` validations will be performed shallowly
recursive: boolean = true ;
// External values that can be provided to validations and conditionals
context ?: object ;
}
Schema.validateSync(value: any, options?: object): InferType<Schema>
يقوم بتشغيل عمليات التحقق من الصحة بشكل متزامن إن أمكن ويعيد القيمة الناتجة، أو يلقي خطأ التحقق من الصحة. يقبل جميع الخيارات نفسها مثل validate
.
يعمل التحقق المتزامن فقط في حالة عدم وجود اختبارات غير متزامنة تم تكوينها، على سبيل المثال، الاختبارات التي تُرجع وعدًا. على سبيل المثال هذا سوف يعمل:
let schema = number ( ) . test (
'is-42' ,
"this isn't the number i want" ,
( value ) => value != 42 ,
) ;
schema . validateSync ( 23 ) ; // throws ValidationError
لكن هذا لن:
let schema = number ( ) . test ( 'is-42' , "this isn't the number i want" , ( value ) =>
Promise . resolve ( value != 42 ) ,
) ;
schema . validateSync ( 42 ) ; // throws Error
Schema.validateAt(path: string, value: any, options?: object): Promise<InferType<Schema>, ValidationError>
التحقق من صحة المسار المتداخل بعمق داخل المخطط. تشبه طريقة عمل reach
، ولكنها تستخدم المخطط الناتج كموضوع للتحقق من الصحة.
ملحوظة!
value
هنا هي القيمة الجذرية المتعلقة بمخطط البداية، وليست القيمة الموجودة في المسار المتداخل.
let schema = object ( {
foo : array ( ) . of (
object ( {
loose : boolean ( ) ,
bar : string ( ) . when ( 'loose' , {
is : true ,
otherwise : ( schema ) => schema . strict ( ) ,
} ) ,
} ) ,
) ,
} ) ;
let rootValue = {
foo : [ { bar : 1 } , { bar : 1 , loose : true } ] ,
} ;
await schema . validateAt ( 'foo[0].bar' , rootValue ) ; // => ValidationError: must be a string
await schema . validateAt ( 'foo[1].bar' , rootValue ) ; // => '1'
Schema.validateSyncAt(path: string, value: any, options?: object): InferType<Schema>
نفس validateAt
ولكنه متزامن.
Schema.isValid(value: any, options?: object): Promise<boolean>
يُرجع true
عندما تتطابق القيمة التي تم تمريرها مع المخطط. isValid
غير متزامن ويعيد كائن Promise.
يأخذ نفس الخيارات مثل validate()
.
Schema.isValidSync(value: any, options?: object): boolean
يُرجع بشكل متزامن true
عندما تتطابق القيمة التي تم تمريرها مع المخطط.
يأخذ نفس الخيارات مثل validateSync()
وله نفس التحذيرات حول اختبارات المزامنة.
Schema.cast(value: any, options = {}): InferType<Schema>
يحاول إجبار القيمة التي تم تمريرها على القيمة التي تطابق المخطط. على سبيل المثال: سيتم تحويل الرقم '5'
إلى 5
عند استخدام النوع number()
. عادةً ما تُرجع عمليات الإرسال الفاشلة null
، ولكنها قد تُرجع أيضًا نتائج مثل NaN
وسلاسل غير متوقعة.
قم بتوفير options
للتحكم بشكل أكثر تحديدًا في سلوك التحقق من validate
.
interface CastOptions < TContext extends { } > {
// Remove undefined properties from objects
stripUnknown : boolean = false ;
// Throws a TypeError if casting doesn't produce a valid type
// note that the TS return type is inaccurate when this is `false`, use with caution
assert ?: boolean = true ;
// External values that used to resolve conditions and references
context ?: TContext ;
}
Schema.isType(value: any): value is InferType<Schema>
يقوم بإجراء فحص النوع مقابل value
التي تم تمريرها. تُرجع صحيحًا إذا تطابقت، ولا تُلقي القيمة. عندما يتم تعيين nullable()
على أنها null
تعتبر قيمة صالحة للنوع. يجب عليك استخدام isType
لجميع عمليات التحقق من نوع المخطط.
Schema.strict(enabled: boolean = false): Schema
يضبط الخيار strict
على true
. تتخطى المخططات الصارمة محاولات الإكراه والتحويل، وتتحقق من صحة القيمة "كما هي".
Schema.strip(enabled: boolean = true): Schema
يضع علامة على المخطط المراد إزالته من كائن الإخراج. يعمل فقط كمخطط متداخل.
let schema = object ( {
useThis : number ( ) ,
notThis : string ( ) . strip ( ) ,
} ) ;
schema . cast ( { notThis : 'foo' , useThis : 4 } ) ; // => { useThis: 4 }
يحتوي المخطط مع تمكين strip
على نوع مستنتج من never
، مما يسمح بإزالتها من النوع العام:
let schema = object ( {
useThis : number ( ) ,
notThis : string ( ) . strip ( ) ,
} ) ;
InferType < typeof schema > ; /*
{
useThis?: number | undefined
}
*/
Schema.withMutation(builder: (current: Schema) => void): void
أولاً، اقتباس ريتش هيكي المطلوب قانونًا:
إذا سقطت شجرة في الغابة هل تصدر صوتا؟
إذا قامت دالة خالصة بتغيير بعض البيانات المحلية من أجل إنتاج قيمة إرجاع غير قابلة للتغيير، فهل هذا جيد؟
يتيح لك withMutation
تغيير المخطط الموجود في مكانه، بدلاً من السلوك الافتراضي الذي يتم استنساخه قبل كل تغيير. بشكل عام، هذا ليس ضروريًا نظرًا لأن الغالبية العظمى من تغييرات المخطط تحدث أثناء الإعلان الأولي، ولا تحدث إلا مرة واحدة طوال عمر المخطط، لذا لا يمثل الأداء مشكلة. ومع ذلك، تحدث بعض الطفرات في وقت الإرسال/التحقق من الصحة، (مثل المخطط الشرطي باستخدام when()
)، أو عند إنشاء كائن مخطط.
object ( )
. shape ( { key : string ( ) } )
. withMutation ( ( schema ) => {
return arrayOfObjectTests . forEach ( ( test ) => {
schema . test ( test ) ;
} ) ;
} ) ;
Schema.default(value: any): Schema
يضبط قيمة افتراضية لاستخدامها عندما تكون القيمة undefined
. يتم إنشاء الإعدادات الافتراضية بعد تنفيذ التحويلات، ولكن قبل عمليات التحقق من الصحة، للمساعدة في ضمان تحديد الإعدادات الافتراضية الآمنة. سيتم استنساخ القيمة الافتراضية في كل استخدام، مما قد يؤدي إلى فرض عقوبات على أداء الكائنات والمصفوفات. لتجنب هذا الحمل يمكنك أيضًا تمرير دالة تُرجع قيمة افتراضية جديدة. لاحظ أن null
تعتبر قيمة منفصلة غير فارغة.
yup . string . default ( 'nothing' ) ;
yup . object . default ( { number : 5 } ) ; // object will be cloned every time a default is needed
yup . object . default ( ( ) => ( { number : 5 } ) ) ; // this is cheaper
yup . date . default ( ( ) => new Date ( ) ) ; // also helpful for defaults that change over time
Schema.getDefault(options?: object): Any
استرداد القيمة الافتراضية المحددة مسبقًا. سوف يقوم getDefault
بحل أي شروط قد تغير الإعداد الافتراضي. يمكنك اختياريًا تمرير options
مع context
(لمزيد من المعلومات حول context
راجع Schema.validate
).
Schema.nullable(message?: string | function): Schema
يشير إلى أن null
هي قيمة صالحة للمخطط. بدون nullable()
يتم التعامل مع null
كنوع مختلف وسوف تفشل عمليات التحقق Schema.isType()
.
let schema = number ( ) . nullable ( ) ;
schema . cast ( null ) ; // null
InferType < typeof schema > ; // number | null
Schema.nonNullable(message?: string | function): Schema
عكس nullable
، يزيل null
من قيم النوع الصالحة للمخطط. المخطط غير قابل للإلغاء بشكل افتراضي .
let schema = number ( ) . nonNullable ( ) ;
schema . cast ( null ) ; // TypeError
InferType < typeof schema > ; // number
Schema.defined(): Schema
تتطلب قيمة للمخطط. جميع قيم الحقول باستثناء undefined
تلبي هذا المطلب.
let schema = string ( ) . defined ( ) ;
schema . cast ( undefined ) ; // TypeError
InferType < typeof schema > ; // string
Schema.optional(): Schema
عكس defined()
يسمح بقيم undefined
للنوع المحدد.
let schema = string ( ) . optional ( ) ;
schema . cast ( undefined ) ; // undefined
InferType < typeof schema > ; // string | undefined
Schema.required(message?: string | function): Schema
قم بوضع علامة على المخطط كما هو مطلوب، مما لن يسمح undefined
أو null
كقيمة. required
يلغي تأثيرات الاتصال optional()
و nullable()
احترس! تعمل
string().required
بشكل مختلف قليلاً وتمنع أيضًا قيم السلسلة الفارغة (''
) عند الحاجة.
Schema.notRequired(): Schema
ضع علامة على المخطط على أنه غير مطلوب. هذا اختصار لـ schema.nullable().optional()
;
Schema.typeError(message: string): Schema
تحديد رسالة خطأ لعمليات التحقق من النوع الفاشلة. يمكن استخدام الاستيفاء ${value}
و ${type}
في وسيطة message
.
Schema.oneOf(arrayOfValues: Array<any>, message?: string | function): Schema
: equals
السماح فقط بالقيم من مجموعة القيم. تتم إزالة القيم المضافة من أي قيم notOneOf
إذا كانت موجودة. يمكن استخدام الاستيفاء ${values}
في وسيطة message
. إذا تم توفير مرجع أو مراجع، فيمكن استخدام الاستيفاء ${resolved}
في وسيطة الرسالة للحصول على القيم التي تم حلها والتي تم التحقق منها في وقت التحقق من الصحة.
لاحظ أن undefined
لا يفشل في أداة التحقق هذه، حتى عندما لا يتم تضمين undefined
في arrayOfValues
. إذا كنت لا تريد أن تكون undefined
قيمة صالحة، فيمكنك استخدام Schema.required
.
let schema = yup . mixed ( ) . oneOf ( [ 'jimmy' , 42 ] ) ;
await schema . isValid ( 42 ) ; // => true
await schema . isValid ( 'jimmy' ) ; // => true
await schema . isValid ( new Date ( ) ) ; // => false
Schema.notOneOf(arrayOfValues: Array<any>, message?: string | function)
عدم السماح بالقيم من مجموعة من القيم. تتم إزالة القيم المضافة من oneOf
القيم إذا كانت موجودة. يمكن استخدام الاستيفاء ${values}
في وسيطة message
. إذا تم توفير مرجع أو مراجع، فيمكن استخدام الاستيفاء ${resolved}
في وسيطة الرسالة للحصول على القيم التي تم حلها والتي تم التحقق منها في وقت التحقق من الصحة.
let schema = yup . mixed ( ) . notOneOf ( [ 'jimmy' , 42 ] ) ;
await schema . isValid ( 42 ) ; // => false
await schema . isValid ( new Date ( ) ) ; // => true
Schema.when(keys: string | string[], builder: object | (values: any[], schema) => Schema): Schema
اضبط المخطط بناءً على حقول الأخوة أو الأخوة. يمكنك توفير كائن حرفي حيث is
القيمة أو وظيفة المطابقة، then
يوفر المخطط الحقيقي و/أو otherwise
لحالة الفشل.
is
مقارنة الشروط بشكل صارم ( ===
) إذا كنت تريد استخدام شكل مختلف من المساواة، فيمكنك توفير وظيفة مثل: is: (value) => value == true
.
يمكنك أيضًا بادئة الخصائص بـ $
لتحديد خاصية تعتمد على context
الذي تم تمريره بواسطة validate()
أو cast
بدلاً من القيمة المدخلة.
when
تكون الشروط مضافة.
then
يتم تحديد وظائف otherwise
(schema: Schema) => Schema
.
let schema = object ( {
isBig : boolean ( ) ,
count : number ( )
. when ( 'isBig' , {
is : true , // alternatively: (val) => val == true
then : ( schema ) => schema . min ( 5 ) ,
otherwise : ( schema ) => schema . min ( 0 ) ,
} )
. when ( '$other' , ( [ other ] , schema ) =>
other === 4 ? schema . max ( 6 ) : schema ,
) ,
} ) ;
await schema . validate ( value , { context : { other : 4 } } ) ;
يمكنك أيضًا تحديد أكثر من مفتاح تابع، وفي هذه الحالة سيتم نشر كل قيمة كوسيطة.
let schema = object ( {
isSpecial : boolean ( ) ,
isBig : boolean ( ) ,
count : number ( ) . when ( [ 'isBig' , 'isSpecial' ] , {
is : true , // alternatively: (isBig, isSpecial) => isBig && isSpecial
then : ( schema ) => schema . min ( 5 ) ,
otherwise : ( schema ) => schema . min ( 0 ) ,
} ) ,
} ) ;
await schema . validate ( {
isBig : true ,
isSpecial : true ,
count : 10 ,
} ) ;
وبدلاً من ذلك، يمكنك توفير دالة تُرجع مخططًا، يتم استدعاؤه باستخدام مجموعة من القيم لكل مفتاح متوفر في المخطط الحالي.
let schema = yup . object ( {
isBig : yup . boolean ( ) ,
count : yup . number ( ) . when ( 'isBig' , ( [ isBig ] , schema ) => {
return isBig ? schema . min ( 5 ) : schema . min ( 0 ) ;
} ) ,
} ) ;
await schema . validate ( { isBig : false , count : 4 } ) ;
Schema.test(name: string, message: string | function | any, test: function): Schema
إضافة وظيفة اختبار إلى سلسلة التحقق من الصحة. يتم إجراء الاختبارات بعد إلقاء أي كائن. تحتوي العديد من الأنواع على بعض الاختبارات المضمنة، ولكن يمكنك إنشاء اختبارات مخصصة بسهولة. من أجل السماح بعمليات التحقق المخصصة غير المتزامنة، يتم تشغيل جميع الاختبارات (أو لا يتم تشغيلها بشكل غير متزامن). ونتيجة لذلك، لا يمكن ضمان أمر تنفيذ الاختبار.
يجب أن توفر جميع الاختبارات name
message
خطأ ووظيفة التحقق التي يجب أن تُرجع true
عندما تكون value
الحالية صالحة false
أو ValidationError
بخلاف ذلك. لإجراء اختبار غير متزامن، يُرجع الوعد الذي يحل true
أو false
أو خطأ ValidationError
.
بالنسبة إلى وسيطة message
، يمكنك توفير سلسلة ستقوم باستيفاء قيم معينة إذا تم تحديدها باستخدام بناء الجملة ${param}
. افتراضيًا، يتم تمرير كافة رسائل الاختبار بقيمة path
تكون ذات قيمة في المخططات المتداخلة.
يتم استدعاء وظيفة test
value
الحالية. لمزيد من عمليات التحقق المتقدمة، يمكنك استخدام التوقيع البديل لتوفير المزيد من الخيارات (انظر أدناه):
let jimmySchema = string ( ) . test (
'is-jimmy' ,
'${path} is not Jimmy' ,
( value , context ) => value === 'jimmy' ,
) ;
// or make it async by returning a promise
let asyncJimmySchema = string ( )
. label ( 'First name' )
. test (
'is-jimmy' ,
( { label } ) => ` ${ label } is not Jimmy` , // a message can also be a function
async ( value , testContext ) =>
( await fetch ( '/is-jimmy/' + value ) ) . responseText === 'true' ,
) ;
await schema . isValid ( 'jimmy' ) ; // => true
await schema . isValid ( 'john' ) ; // => false
يتم استدعاء وظائف الاختبار بقيمة سياق خاصة، باعتبارها الوسيطة الثانية، التي تكشف عن بعض البيانات التعريفية والوظائف المفيدة. بالنسبة للوظائف غير السهمية، يتم أيضًا تعيين سياق الاختبار كوظيفة this
. انتبه، إذا قمت بالوصول إليه عبر this
فلن يعمل في وظيفة السهم.
testContext.path
: مسار السلسلة للتحقق من الصحة الحاليtestContext.schema
: كائن المخطط الذي تم حله والذي يجري الاختبار عليه.testContext.options
: تم استدعاء كائن options
الذي يستخدم التحقق من صحة () أو isValid ().testContext.parent
: في حالة المخطط المتداخل، هذه هي قيمة الكائن الأصليtestContext.originalValue
: القيمة الأصلية التي يتم اختبارهاtestContext.createError(Object: { path: String, message: String, params: Object })
: إنشاء خطأ التحقق من الصحة وإرجاعه. مفيد لتعيين path
أو params
أو message
الخطأ ديناميكيًا. إذا تم حذف أي من الخيارين فإنه سيتم استخدام المسار الحالي، أو الرسالة الافتراضية. Schema.test(options: object): Schema
test(..)
التوقيع. options
هي كائن يحتوي على بعض الخيارات التالية:
Options = {
// unique name identifying the test
name : string ;
// test function, determines schema validity
test: ( value : any ) => boolean ;
// the validation error message
message: string ;
// values passed to message for interpolation
params: ? object ;
// mark the test as exclusive, meaning only one test of the same name can be active at once
exclusive: boolean = false ;
}
في حالة الخلط بين الاختبارات الحصرية وغير الحصرية يتم استخدام المنطق التالي. إذا تمت إضافة اختبار غير حصري إلى مخطط يحتوي على اختبار حصري بنفس الاسم، فسيتم إزالة الاختبار الحصري وسيتم تجميع اختبارات أخرى بنفس الاسم.
إذا تمت إضافة اختبار حصري إلى مخطط يحتوي على اختبارات غير حصرية بنفس الاسم، فستتم إزالة الاختبارات السابقة وستحل الاختبارات الإضافية التي تحمل نفس الاسم محل بعضها البعض.
let max = 64 ;
let schema = yup . string ( ) . test ( {
name : 'max' ,
exclusive : true ,
params : { max } ,
message : '${path} must be less than ${max} characters' ,
test : ( value ) => value == null || value . length <= max ,
} ) ;
Schema.transform((currentValue: any, originalValue: any) => any): Schema
يضيف تحويلاً إلى سلسلة التحويل. تعد التحويلات أمرًا أساسيًا في عملية الصب، حيث تقوم التحويلات الافتراضية لكل نوع بإجبار القيم على النوع المحدد (كما تم التحقق منها بواسطة isType()
). يتم تشغيل التحويلات قبل عمليات التحقق من الصحة ويتم تطبيقها فقط عندما لا يتم وضع علامة على المخطط على أنه strict
(الافتراضي). وقد بنيت بعض الأنواع في التحولات.
تعتبر التحويلات مفيدة في تغيير كيفية تشكيل الكائن بشكل تعسفي، ومع ذلك، يجب عليك الحرص على عدم تغيير القيمة التي تم تمريرها. يتم تشغيل التحويلات بشكل تسلسلي بحيث تمثل كل value
الحالة الحالية للإرسال، ويمكنك استخدام معلمة originalValue
إذا كنت بحاجة إلى العمل على القيمة الأولية الأولية.
let schema = string ( ) . transform ( ( value , originalValue ) => {
return this . isType ( value ) && value !== null ? value . toUpperCase ( ) : value ;
} ) ;
schema . cast ( 'jimmy' ) ; // => 'JIMMY'
سيتعامل كل نوع مع الإكراه الأساسي للقيم على النوع المناسب لك، ولكن في بعض الأحيان قد ترغب في تعديل السلوك الافتراضي أو تحسينه. على سبيل المثال، إذا أردت استخدام إستراتيجية تحليل تاريخ مختلفة عن الإستراتيجية الافتراضية، فيمكنك القيام بذلك باستخدام التحويل.
module . exports = function ( formats = 'MMM dd, yyyy' ) {
return date ( ) . transform ( ( value , originalValue , context ) => {
// check to see if the previous transform already parsed the date
if ( context . isType ( value ) ) return value ;
// the default coercion failed so let's try it with Moment.js instead
value = Moment ( originalValue , formats ) ;
// if it's valid return the date object, otherwise return an `InvalidDate`
return value . isValid ( ) ? value . toDate ( ) : new Date ( '' ) ;
} ) ;
} ;
ينشئ مخططًا يطابق جميع الأنواع، أو فقط تلك التي قمت بتكوينها. يرث من Schema
. تمتد الأنواع المختلطة {}
افتراضيًا بدلاً من any
أو unknown
. هذا لأنه في TypeScript {}
يعني أي شيء غير null
أو undefined
والذي يعامله بشكل واضح.
import { mixed , InferType } from 'yup' ;
let schema = mixed ( ) . nullable ( ) ;
schema . validateSync ( 'string' ) ; // 'string';
schema . validateSync ( 1 ) ; // 1;
schema . validateSync ( new Date ( ) ) ; // Date;
InferType < typeof schema > ; // {} | undefined
InferType < typeof schema . nullable ( ) . defined ( ) > ; // {} | null
يمكن تنفيذ الأنواع المخصصة عن طريق تمرير وظيفة check
النوع. سيؤدي هذا أيضًا إلى تضييق نوع TypeScript للمخطط.
import { mixed , InferType } from 'yup' ;
let objectIdSchema = yup
. mixed ( ( input ) : input is ObjectId => input instanceof ObjectId )
. transform ( ( value : any , input , ctx ) => {
if ( ctx . isType ( value ) ) return value ;
return new ObjectId ( value ) ;
} ) ;
await objectIdSchema . validate ( ObjectId ( '507f1f77bcf86cd799439011' ) ) ; // ObjectId("507f1f77bcf86cd799439011")
await objectIdSchema . validate ( '507f1f77bcf86cd799439011' ) ; // ObjectId("507f1f77bcf86cd799439011")
InferType < typeof objectIdSchema > ; // ObjectId
تحديد مخطط السلسلة. يرث من Schema
.
let schema = yup . string ( ) ;
await schema . isValid ( 'hello' ) ; // => true
بشكل افتراضي، منطق cast
string
هو استدعاء toString
على القيمة إذا كانت موجودة.
لا يتم فرض القيم الفارغة (استخدم ensure()
لإجبار القيم الفارغة على سلاسل فارغة).
تقوم عمليات الإرسال الفاشلة بإرجاع قيمة الإدخال.
string.required(message?: string | function): Schema
نفس المخطط mixed()
المطلوب، باستثناء أن السلاسل الفارغة تعتبر أيضًا قيمًا "مفقودة".
string.length(limit: number | Ref, message?: string | function): Schema
قم بتعيين الطول المطلوب لقيمة السلسلة. يمكن استخدام الاستيفاء ${length}
في وسيطة message
string.min(limit: number | Ref, message?: string | function): Schema
قم بتعيين الحد الأدنى لطول قيمة السلسلة. يمكن استخدام الاستيفاء ${min}
في وسيطة message
string.max(limit: number | Ref, message?: string | function): Schema
قم بتعيين الحد الأقصى لطول قيمة السلسلة. يمكن استخدام الاستيفاء ${max}
في وسيطة message
string.matches(regex: Regex, message?: string | function): Schema
قم بتوفير regex
تعسفي لمطابقة القيمة مقابلها.
let schema = string ( ) . matches ( / (hi|bye) / ) ;
await schema . isValid ( 'hi' ) ; // => true
await schema . isValid ( 'nope' ) ; // => false
string.matches(regex: Regex, options: { message: string, excludeEmptyString: bool }): Schema
توقيع بديل لـ string.matches
مع كائن الخيارات. excludeEmptyString
، عندما تكون الدوائر القصيرة صحيحة، يتم اختبار التعبير العادي عندما تكون القيمة عبارة عن سلسلة فارغة، مما يجعل من الأسهل تجنب مطابقة أي شيء دون تعقيد التعبير العادي.
let schema = string ( ) . matches ( / (hi|bye) / , { excludeEmptyString : true } ) ;
await schema . isValid ( '' ) ; // => true
string.email(message?: string | function): Schema
يتحقق من صحة القيمة كعنوان بريد إلكتروني باستخدام نفس التعبير العادي كما هو محدد في مواصفات HTML.
انتبه: التحقق من صحة عناوين البريد الإلكتروني يكاد يكون مستحيلًا باستخدام الرمز فقط. يقبل العملاء والخوادم المختلفة أشياء مختلفة ويختلف الكثير منها عن المواصفات المختلفة التي تحدد رسائل البريد الإلكتروني "الصالحة". الطريقة الحقيقية الوحيدة للتحقق من صحة عنوان البريد الإلكتروني هي إرسال رسالة تحقق إليه والتحقق من حصول المستخدم عليها. مع أخذ ذلك في الاعتبار، يختار yup تعبيرًا عاديًا بسيطًا نسبيًا لا يغطي جميع الحالات، ولكنه يتماشى مع سلوك التحقق من صحة إدخال المتصفح نظرًا لأن نماذج HTML هي حالة استخدام شائعة لـ yup.
إذا كانت لديك احتياجات أكثر تحديدًا، فيرجى تجاوز طريقة البريد الإلكتروني باستخدام المنطق أو التعبير العادي الخاص بك:
yup . addMethod ( yup . string , 'email' , function validateEmail ( message ) {
return this . matches ( myEmailRegex , {
message ,
name : 'email' ,
excludeEmptyString : true ,
} ) ;
} ) ;
string.url(message?: string | function): Schema
يتحقق من صحة القيمة كعنوان URL صالح عبر regex.
string.uuid(message?: string | function): Schema
التحقق من صحة القيمة باعتبارها UUID صالحًا عبر regex.
string.datetime(options?: {message?: string | function, allowOffset?: boolean, precision?: number})
التحقق من صحة القيمة باعتبارها وقت تاريخ ISO عبر regex. الإعدادات الافتراضية للتحقق من صحة UTC؛ لا يُسمح بإزاحة المنطقة الزمنية (راجع options.allowOffset
).
على عكس .date()
، لن يقوم datetime
بتحويل السلسلة إلى كائن Date
. يوفر datetime
أيضًا تخصيصًا أكبر للتنسيق المطلوب لسلسلة التاريخ والوقت مقارنةً date
.
options.allowOffset
: السماح بإزاحة المنطقة الزمنية. يتطلب الخطأ المنطقة الزمنية UTC 'Z'. (الافتراضي: خطأ) options.precision
: يتطلب دقة معينة في الثانية الفرعية في التاريخ. (الافتراضي: null - أي (أو لا) دقة ثانية فرعية)
string.datetime(message?: string | function)
توقيع بديل لـ string.datetime
يمكن استخدامه عندما لا تحتاج إلى تمرير خيارات أخرى غير message
.
string.ensure(): Schema
يحول القيم undefined
null
إلى سلسلة فارغة مع ضبط القيمة default
على سلسلة فارغة.
string.trim(message?: string | function): Schema
يحول قيم السلسلة عن طريق إزالة المسافات البيضاء البادئة والزائدة. إذا تم ضبط الدالة strict()
فإنها ستتحقق فقط من اقتطاع القيمة.
string.lowercase(message?: string | function): Schema
يحول قيمة السلسلة إلى أحرف صغيرة. إذا تم ضبط الدالة strict()
فإنها ستتحقق فقط من أن القيمة صغيرة.
string.uppercase(message?: string | function): Schema
يحول قيمة السلسلة إلى أحرف كبيرة. إذا تم ضبط الدالة strict()
فإنها ستتحقق فقط من أن القيمة كبيرة.
تحديد مخطط الأرقام. يرث من Schema
.
let schema = yup . number ( ) ;
await schema . isValid ( 10 ) ; // => true
منطق cast
الافتراضي number
هو: parseFloat
.
ترجع القوالب الفاشلة NaN
.
number.min(limit: number | Ref, message?: string | function): Schema
قم بتعيين الحد الأدنى للقيمة المسموح بها. يمكن استخدام الاستيفاء ${min}
في وسيطة message
.
number.max(limit: number | Ref, message?: string | function): Schema
قم بتعيين الحد الأقصى للقيمة المسموح بها. يمكن استخدام الاستيفاء ${max}
في وسيطة message
.
number.lessThan(max: number | Ref, message?: string | function): Schema
يجب أن تكون القيمة أقل من max
. يمكن استخدام الاستيفاء ${less}
في وسيطة message
.
number.moreThan(min: number | Ref, message?: string | function): Schema
يجب أن تكون القيمة أكبر من min
. يمكن استخدام الاستيفاء ${more}
في وسيطة message
.
number.positive(message?: string | function): Schema
يجب أن تكون القيمة رقمًا موجبًا.
number.negative(message?: string | function): Schema
يجب أن تكون القيمة رقمًا سالبًا.
number.integer(message?: string | function): Schema
التحقق من أن الرقم هو عدد صحيح.
number.truncate(): Schema
التحويل الذي يفرض القيمة على عدد صحيح عن طريق تجريد الأرقام الموجودة على يمين العلامة العشرية.
number.round(type: 'floor' | 'ceil' | 'trunc' | 'round' = 'round'): Schema
يضبط القيمة عبر الطريقة المحددة Math
(الإعداد الافتراضي هو "جولة").
تحديد مخطط منطقي. يرث من Schema
.
let schema = yup . boolean ( ) ;
await schema . isValid ( true ) ; // => true
تحديد مخطط التاريخ. افتراضيًا، سيتم تحليل سلاسل تاريخ ISO بشكل صحيح، للحصول على خيارات تحليل أكثر قوة، راجع أنواع المخططات الموسعة في نهاية الملف التمهيدي. يرث من Schema
.
let schema = yup . date ( ) ;
await schema . isValid ( new Date ( ) ) ; // => true
منطق cast
الافتراضي date
هو تمرير القيمة إلى مُنشئ Date
، وفي حالة فشل ذلك، سيحاول تحليل التاريخ كسلسلة تاريخ ISO.
إذا كنت تريد عدم تحويل سلاسل ISO إلى كائن
Date
، فاستخدم.datetime()
بدلاً من ذلك.
تُرجع عمليات الإرسال الفاشلة تاريخًا غير صالح.
date.min(limit: Date | string | Ref, message?: string | function): Schema
قم بتعيين الحد الأدنى للتاريخ المسموح به. عندما يتم توفير سلسلة، ستحاول الإرسال إلى تاريخ أولاً واستخدام النتيجة كحد أقصى.
date.max(limit: Date | string | Ref, message?: string | function): Schema
قم بتعيين الحد الأقصى للتاريخ المسموح به، عندما يتم توفير سلسلة، ستحاول إرسال التاريخ أولاً واستخدام النتيجة كحد أقصى.
تعريف مخطط المصفوفة. يمكن كتابة المصفوفات أم لا، عند تحديد نوع العنصر، سيتم تطبيق cast
و isValid
على العناصر أيضًا. يتم أيضًا تمرير الخيارات التي تم تمريرها إلى isValid
إلى المخططات الفرعية.
يرث من Schema
.
let schema = yup . array ( ) . of ( yup . number ( ) . min ( 2 ) ) ;
await schema . isValid ( [ 2 , 3 ] ) ; // => true
await schema . isValid ( [ 1 , - 24 ] ) ; // => false
schema . cast ( [ '2' , '3' ] ) ; // => [2, 3]
يمكنك أيضًا تمرير مخطط النوع الفرعي إلى مُنشئ المصفوفة كوسيلة راحة.
array ( ) . of ( yup . number ( ) ) ;
// or
array ( yup . number ( ) ) ;
المصفوفات ليس لها سلوك الصب الافتراضي.
array.of(type: Schema): this
تحديد مخطط عناصر المصفوفة. of()
اختياري، وعند حذفه، لن يتحقق مخطط المصفوفة من صحة محتوياته.
array.json(): this
حاول تحليل قيم سلسلة الإدخال كـ JSON باستخدام JSON.parse
.
array.length(length: number | Ref, message?: string | function): this
قم بتعيين متطلبات طول محددة للمصفوفة. يمكن استخدام الاستيفاء ${length}
في وسيطة message
.
array.min(limit: number | Ref, message?: string | function): this
قم بتعيين الحد الأدنى لطول المصفوفة. يمكن استخدام الاستيفاء ${min}
في وسيطة message
.
array.max(limit: number | Ref, message?: string | function): this
قم بتعيين الحد الأقصى لطول المصفوفة. يمكن استخدام الاستيفاء ${max}
في وسيطة message
.
array.ensure(): this
يضمن أن القيمة عبارة عن مصفوفة، عن طريق تعيين القيمة الافتراضية إلى []
وتحويل القيم null
undefined
إلى مصفوفة فارغة أيضًا. سيتم تغليف أي قيمة غير فارغة وغير مصفوفة في مصفوفة.
array ( ) . ensure ( ) . cast ( null ) ; // => []
array ( ) . ensure ( ) . cast ( 1 ) ; // => [1]
array ( ) . ensure ( ) . cast ( [ 1 ] ) ; // => [1]
array.compact(rejector: (value) => boolean): Schema
يزيل القيم الزائفة من المصفوفة. يتيح لك توفير وظيفة الرفض تحديد معايير الرفض بنفسك.
array ( ) . compact ( ) . cast ( [ '' , 1 , 0 , 4 , false , null ] ) ; // => [1, 4]
array ( )
. compact ( function ( v ) {
return v == null ;
} )
. cast ( [ '' , 1 , 0 , 4 , false , null ] ) ; // => ['', 1, 0, 4, false]
Tuples، هي صفائف ذات طول ثابت حيث يكون لكل عنصر نوع مميز.
يرث من Schema
.
import { tuple , string , number , InferType } from 'yup' ;
let schema = tuple ( [
string ( ) . label ( 'name' ) ,
number ( ) . label ( 'age' ) . positive ( ) . integer ( ) ,
] ) ;
await schema . validate ( [ 'James' , 3 ] ) ; // ['James', 3]
await schema . validate ( [ 'James' , - 24 ] ) ; // => ValidationError: age must be a positive number
InferType < typeof schema > // [string, number] | undefined
ليس لدى الصفوف سلوك الصب الافتراضي.
تحديد مخطط الكائن. يتم أيضًا تمرير الخيارات التي تم تمريرها إلى isValid
إلى المخططات الفرعية. يرث من Schema
.
yup . object ( {
name : string ( ) . required ( ) ,
age : number ( ) . required ( ) . positive ( ) . integer ( ) ,
email : string ( ) . email ( ) ,
website : string ( ) . url ( ) ,
} ) ;
لم يتم تطبيق أي تحويلات افتراضية في مخطط الكائن.
يأتي مخطط الكائن بقيمة افتراضية تم تعيينها بالفعل، والتي "تبني" شكل الكائن، وتحدد أي إعدادات افتراضية للحقول:
let schema = object ( {
name : string ( ) . default ( '' ) ,
} ) ;
schema . default ( ) ; // -> { name: '' }
قد يكون هذا مفاجئًا بعض الشيء، ولكنه عادةً ما يكون مفيدًا لأنه يسمح لمخطط كبير ومتداخل بإنشاء قيم افتراضية تملأ الشكل بالكامل وليس فقط الكائن الجذر. هناك مسكتك واحدة! رغم ذلك. بالنسبة لمخطط الكائنات المتداخلة الاختياري ولكنه يتضمن حقولًا غير اختيارية، فقد يفشل بطرق غير متوقعة:
let schema = object ( {
id : string ( ) . required ( ) ,
names : object ( {
first : string ( ) . required ( ) ,
} ) ,
} ) ;
schema . isValid ( { id : 1 } ) ; // false! names.first is required
وذلك لأن yup يلقي كائن الإدخال قبل تشغيل التحقق من الصحة والذي سينتج عنه:
{ id: '1', names: { first: undefined }}
خلال مرحلة التحقق من صحة names
موجودة، ويتم التحقق من صحتها، العثور على names.first
مفقود. إذا كنت ترغب في تجنب هذا السلوك، فقم بأحد الإجراءات التالية:
names.default(undefined)
names.nullable().default(null)
object.shape(fields: object, noSortEdges?: Array<[string, string]>): Schema
تحديد مفاتيح الكائن والمخططات للمفاتيح المذكورة.
لاحظ أنه يمكنك استخدام طريقة سلسلة shape
، والتي تعمل مثل Object.assign
.
object ( {
a : string ( ) ,
b : number ( ) ,
} ) . shape ( {
b : string ( ) ,
c : number ( ) ,
} ) ;
سيكون بالضبط نفس:
object ( {
a : string ( ) ,
b : string ( ) ,
c : number ( ) ,
} ) ;
object.json(): this
حاول تحليل قيم سلسلة الإدخال كـ JSON باستخدام JSON.parse
.
object.concat(schemaB: ObjectSchema): ObjectSchema
ينشئ مخطط كائن، من خلال تطبيق جميع الإعدادات والحقول من schemaB
على القاعدة، مما يؤدي إلى إنتاج مخطط جديد. يتم دمج شكل الكائن بشكل سطحي مع الحقول المشتركة من schemaB
مع إعطاء الأولوية للحقول الأساسية.
object.pick(keys: string[]): Schema
قم بإنشاء مخطط جديد من مجموعة فرعية من الحقول الأصلية.
let person = object ( {
age : number ( ) . default ( 30 ) . required ( ) ,
name : string ( ) . default ( 'pat' ) . required ( ) ,
color : string ( ) . default ( 'red' ) . required ( ) ,
} ) ;
let nameAndAge = person . pick ( [ 'name' , 'age' ] ) ;
nameAndAge . getDefault ( ) ; // => { age: 30, name: 'pat'}
object.omit(keys: string[]): Schema
قم بإنشاء مخطط جديد مع حذف الحقول.
let person = object ( {
age : number ( ) . default ( 30 ) . required ( ) ,
name : string ( ) . default ( 'pat' ) . required ( ) ,
color : string ( ) . default ( 'red' ) . required ( ) ,
} ) ;
let nameAndAge = person . omit ( [ 'color' ] ) ;
nameAndAge . getDefault ( ) ; // => { age: 30, name: 'pat'}
object.from(fromKey: string, toKey: string, alias: boolean = false): this
يحول المفتاح المحدد إلى مفتاح جديد. إذا كان alias
true
فسيتم ترك المفتاح القديم.
let schema = object ( {
myProp : mixed ( ) ,
Other : mixed ( ) ,
} )
. from ( 'prop' , 'myProp' )
. from ( 'other' , 'Other' , true ) ;
schema . cast ( { prop : 5 , other : 6 } ) ; // => { myProp: 5, other: 6, Other: 6 }
object.noUnknown(onlyKnownKeys: boolean = true, message?: string | function): Schema
تحقق من أن قيمة الكائن تحتوي فقط على المفاتيح المحددة في shape
، وقم false
كوسيطة أولى لتعطيل عملية التحقق. تقييد المفاتيح المعروفة، يؤدي أيضًا إلى تمكين خيار stripUnknown
، عندما لا يكون في الوضع الصارم.
object.camelCase(): Schema
يحول كافة مفاتيح الكائنات إلى CamelCase
object.constantCase(): Schema
يحول كافة مفاتيح الكائنات إلى CONSTANT_CASE.