@travetto/schema
Advanced tools
Comparing version 5.0.12 to 5.0.13
{ | ||
"name": "@travetto/schema", | ||
"version": "5.0.12", | ||
"version": "5.0.13", | ||
"description": "Data type registry for runtime validation, reflection and binding.", | ||
@@ -30,3 +30,3 @@ "keywords": [ | ||
"dependencies": { | ||
"@travetto/registry": "^5.0.12" | ||
"@travetto/registry": "^5.0.13" | ||
}, | ||
@@ -33,0 +33,0 @@ "peerDependencies": { |
@@ -66,24 +66,24 @@ <!-- This file was generated by @travetto/doc and should not be modified directly --> | ||
This schema provides a powerful base for data binding and validation at runtime. Additionally there may be types that cannot be detected, or some information that the programmer would like to override. Below are the supported field decorators: | ||
* [@Field](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L30) defines a field that will be serialized. | ||
* [@Required](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L70) defines a that field should be required | ||
* [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L77) defines the allowable values that a field can have | ||
* [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L98) defines a regular expression that the field value should match | ||
* [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L106) enforces min length of a string | ||
* [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L116) enforces max length of a string | ||
* [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L106) enforces min value for a date or a number | ||
* [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L116) enforces max value for a date or a number | ||
* [@Email](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L143) ensures string field matches basic email regex | ||
* [@Telephone](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L150) ensures string field matches basic telephone regex | ||
* [@Url](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L157) ensures string field matches basic url regex | ||
* [@Ignore](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L196) exclude from auto schema registration | ||
* [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L171) ensures number passed in is only a whole number | ||
* [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L177) ensures number passed in allows fractional values | ||
* [@Currency](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L189) provides support for standard currency | ||
* [@Text](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L85) indicates that a field is expecting natural language input, not just discrete values | ||
* [@LongText](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L90) same as text, but expects longer form content | ||
* [@Readonly](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L57) defines a that field should not be bindable external to the class | ||
* [@Writeonly](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L51) defines a that field should not be exported in serialization, but that it can be bound to | ||
* [@Secret](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L63) marks a field as being sensitive. This is used by certain logging activities to ensure sensitive information is not logged out. | ||
* [@Specifier](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L205) attributes additional specifiers to a field, allowing for more specification beyond just the field's type. | ||
* [@SubTypeField](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L211) allows for promoting a given field as the owner of the sub type discriminator (defaults to `type`). | ||
* [@Field](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L25) defines a field that will be serialized. | ||
* [@Required](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L65) defines a that field should be required | ||
* [@Enum](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L72) defines the allowable values that a field can have | ||
* [@Match](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L93) defines a regular expression that the field value should match | ||
* [@MinLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L101) enforces min length of a string | ||
* [@MaxLength](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L111) enforces max length of a string | ||
* [@Min](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L101) enforces min value for a date or a number | ||
* [@Max](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L111) enforces max value for a date or a number | ||
* [@Email](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L138) ensures string field matches basic email regex | ||
* [@Telephone](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L145) ensures string field matches basic telephone regex | ||
* [@Url](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L152) ensures string field matches basic url regex | ||
* [@Ignore](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L191) exclude from auto schema registration | ||
* [@Integer](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L166) ensures number passed in is only a whole number | ||
* [@Float](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L172) ensures number passed in allows fractional values | ||
* [@Currency](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L184) provides support for standard currency | ||
* [@Text](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L80) indicates that a field is expecting natural language input, not just discrete values | ||
* [@LongText](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L85) same as text, but expects longer form content | ||
* [@Readonly](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L52) defines a that field should not be bindable external to the class | ||
* [@Writeonly](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L46) defines a that field should not be exported in serialization, but that it can be bound to | ||
* [@Secret](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L58) marks a field as being sensitive. This is used by certain logging activities to ensure sensitive information is not logged out. | ||
* [@Specifier](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L200) attributes additional specifiers to a field, allowing for more specification beyond just the field's type. | ||
* [@SubTypeField](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L206) allows for promoting a given field as the owner of the sub type discriminator (defaults to `type`). | ||
Additionally, schemas can be nested to form more complex data structures that are able to bound and validated. | ||
@@ -106,3 +106,3 @@ | ||
export class ParamUsage { | ||
main(@Match(NAME_REGEX).Param name: string, @Min(20).Param age?: number) { | ||
main(@Match(NAME_REGEX) name: string, @Min(20) age?: number) { | ||
console.log('Valid name and age!', { name, age }); | ||
@@ -109,0 +109,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import { Any, castTo, ClassInstance } from '@travetto/runtime'; | ||
import { Any, ClassInstance } from '@travetto/runtime'; | ||
@@ -7,8 +7,6 @@ import { SchemaRegistry } from '../service/registry'; | ||
type PropType<V> = (<T extends Partial<Record<K, V>>, K extends string>(t: T, k: K, idx?: TypedPropertyDescriptor<Any> | number) => void) & { | ||
Param: (t: unknown, k: string, idx: number) => void; | ||
}; | ||
type PropType<V> = (<T extends Partial<Record<K, V | Function>>, K extends string>(t: T, k: K, idx?: TypedPropertyDescriptor<Any> | number) => void); | ||
function prop<V>(obj: Partial<FieldConfig>): PropType<V> { | ||
const fn = (t: ClassInstance, k: string, idx?: number | TypedPropertyDescriptor<Any>): void => { | ||
return (t: ClassInstance, k: string, idx?: number | TypedPropertyDescriptor<Any>): void => { | ||
if (idx !== undefined && typeof idx === 'number') { | ||
@@ -20,5 +18,2 @@ SchemaRegistry.registerPendingParamFacet(t.constructor, k, idx, obj); | ||
}; | ||
fn.Param = fn; | ||
return castTo(fn); | ||
} | ||
@@ -25,0 +20,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { castTo, Class, DeepPartial } from '@travetto/runtime'; | ||
import { Any, castTo, Class, ClassInstance, DeepPartial } from '@travetto/runtime'; | ||
@@ -6,3 +6,3 @@ import { BindUtil } from '../bind-util'; | ||
import { ClassConfig, ViewFieldsConfig } from '../service/types'; | ||
import { ValidatorFn } from '../validate/types'; | ||
import { MethodValidatorFn, ValidatorFn } from '../validate/types'; | ||
@@ -30,8 +30,19 @@ /** | ||
*/ | ||
export function Validator<T>(fn: ValidatorFn<T, string>) { | ||
return (target: Class<T>): void => { | ||
export const Validator = <T>(fn: ValidatorFn<T, string>) => | ||
(target: Class<T>, k?: string): void => { | ||
SchemaRegistry.getOrCreatePending(target).validators!.push(castTo(fn)); | ||
}; | ||
/** | ||
* Add a custom validator for a given method | ||
* | ||
* @param fn The validator function | ||
*/ | ||
export function MethodValidator<T extends (...args: Any[]) => Any>(fn: MethodValidatorFn<Parameters<T>>) { | ||
return (target: ClassInstance, k: string, prop: TypedPropertyDescriptor<T>): void => { | ||
SchemaRegistry.registerPendingMethod(target.constructor, k).validators!.push(castTo(fn)); | ||
}; | ||
} | ||
/** | ||
@@ -38,0 +49,0 @@ * Register a specific view for a class |
@@ -1,7 +0,8 @@ | ||
import { Class, AppError, describeFunction, castTo, classConstruct, asFull, castKey } from '@travetto/runtime'; | ||
import { Class, AppError, describeFunction, castTo, classConstruct, asFull, castKey, Any } from '@travetto/runtime'; | ||
import { MetadataRegistry, RootRegistry, ChangeEvent } from '@travetto/registry'; | ||
import { ClassList, FieldConfig, ClassConfig, SchemaConfig, ViewFieldsConfig, ViewConfig } from './types'; | ||
import { ClassList, FieldConfig, ClassConfig, SchemaConfig, ViewFieldsConfig, ViewConfig, SchemaMethodConfig } from './types'; | ||
import { SchemaChangeListener } from './changes'; | ||
import { AllViewⲐ } from '../internal/types'; | ||
import { MethodValidatorFn } from '../validate/types'; | ||
@@ -221,6 +222,15 @@ const classToSubTypeName = (cls: Class): string => cls.name | ||
getMethodSchema<T>(cls: Class<T>, method: string): FieldConfig[] { | ||
return (this.get(cls)?.methods?.[method] ?? []).filter(x => !!x).sort((a, b) => a.index! - b.index!); | ||
return (this.get(cls)?.methods?.[method] ?? {}).fields?.filter(x => !!x).sort((a, b) => a.index! - b.index!) ?? []; | ||
} | ||
/** | ||
* Get method validators | ||
* @param cls | ||
* @param method | ||
*/ | ||
getMethodValidators<T>(cls: Class<T>, method: string): MethodValidatorFn<unknown[]>[] { | ||
return (this.get(cls)?.methods?.[method] ?? {}).validators ?? []; | ||
} | ||
/** | ||
* Register a view | ||
@@ -240,2 +250,12 @@ * @param target The target class | ||
/** | ||
* Register pending method, and establish a method config | ||
* @param target | ||
* @param method | ||
*/ | ||
registerPendingMethod(target: Class, method: string): SchemaMethodConfig { | ||
const methods = this.getOrCreatePending(target)!.methods!; | ||
return (methods[method] ??= { fields: [], validators: [] }); | ||
} | ||
/** | ||
* Register a partial config for a pending method param | ||
@@ -248,4 +268,3 @@ * @param target The class to target | ||
registerPendingParamFacet(target: Class, method: string, idx: number, config: Partial<FieldConfig>): Class { | ||
const methods = this.getOrCreatePending(target)!.methods!; | ||
const params = (methods[method] ??= []); | ||
const params = this.registerPendingMethod(target, method).fields; | ||
if (config.name === '') { | ||
@@ -252,0 +271,0 @@ delete config.name; |
import { Any, Class, Primitive } from '@travetto/runtime'; | ||
import { AllViewⲐ } from '../internal/types'; | ||
import { ValidatorFn } from '../validate/types'; | ||
import { MethodValidatorFn, ValidatorFn } from '../validate/types'; | ||
@@ -30,2 +30,10 @@ export type ClassList = Class | [Class]; | ||
/** | ||
* Basic structure for a method configuration | ||
*/ | ||
export interface SchemaMethodConfig { | ||
fields: FieldConfig[]; | ||
validators: MethodValidatorFn<unknown[]>[]; | ||
} | ||
/** | ||
* Schema configuration | ||
@@ -89,3 +97,3 @@ */ | ||
*/ | ||
methods: Record<string, FieldConfig[]>; | ||
methods: Record<string, SchemaMethodConfig>; | ||
} | ||
@@ -92,0 +100,0 @@ |
@@ -68,5 +68,12 @@ export type ValidationKindCore = 'required' | 'match' | 'min' | 'max' | 'minlength' | 'maxlength' | 'enum' | 'type'; | ||
type OrPromise<T> = T | Promise<T>; | ||
/** | ||
* Validator function | ||
*/ | ||
export type ValidatorFn<T, U> = (value: T, parent?: U) => ValidationError | undefined | Promise<ValidationError | undefined>; | ||
export type ValidatorFn<T, U> = (value: T, parent?: U) => OrPromise<ValidationError | ValidationError[] | undefined>; | ||
/** | ||
* Method Validator function | ||
*/ | ||
export type MethodValidatorFn<T extends unknown[]> = (...value: T) => OrPromise<ValidationError | ValidationError[] | undefined>; |
@@ -236,3 +236,7 @@ import { castKey, castTo, Class, ClassInstance, TypedObject } from '@travetto/runtime'; | ||
if (res) { | ||
errors.push(res); | ||
if (Array.isArray(res)) { | ||
errors.push(...res); | ||
} else { | ||
errors.push(res); | ||
} | ||
} | ||
@@ -328,2 +332,12 @@ } catch (err: unknown) { | ||
} | ||
for (const validator of SchemaRegistry.getMethodValidators(cls, method)) { | ||
const res = await validator(...params); | ||
if (res) { | ||
if (Array.isArray(res)) { | ||
errors.push(...res); | ||
} else { | ||
errors.push(res); | ||
} | ||
} | ||
} | ||
if (errors.length) { | ||
@@ -330,0 +344,0 @@ throw new ValidationResultError(errors); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
103886
2380
Updated@travetto/registry@^5.0.13