schema-to-yup
Advanced tools
Comparing version 1.11.13 to 1.11.14
@@ -1,2 +0,2 @@ | ||
var t=require("yup"),e=require("uniq"),s=require("dashify"),r=require("uppercamelcase");function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}function n(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach(function(s){if("default"!==s){var r=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,r.get?r:{enumerable:!0,get:function(){return t[s]}})}}),e.default=t,e}var a=/*#__PURE__*/n(t),o=/*#__PURE__*/i(e),h=/*#__PURE__*/i(s),l=/*#__PURE__*/i(r);const c={getProps:t=>t&&t.properties,getType:t=>t&&t.type,getName:t=>t&&(t.name||t.title),getConstraints:t=>t,isString:t=>t&&"string"===t.type,isArray:t=>t&&"array"===t.type,isInteger:t=>t&&("integer"===t.type||"int"===t.type),isBoolean:t=>t&&"boolean"===t.type,hasDateFormat:t=>t&&["date","date-time"].find(e=>e===t.format),isDate:t=>t&&"string"===t.type&&c.hasDateFormat(t.format),isNumber:t=>t&&("number"===t.type||c.isInteger(t)),isObject:t=>t&&"object"===t.type,isRequired:t=>t&&t.required},u={getProps:t=>t.properties,getType:t=>t.type,getName:t=>t.name||t.title,getConstraints:t=>t,isString:t=>"string"===t.type&&!u.hasDateFormat(t),isArray:t=>"array"===t.type,isBoolean:t=>"boolean"===t.type,isInteger:t=>"integer"===t.type,hasDateFormat:t=>t&&["date","date-time"].find(e=>e===t.format),isDate:t=>"string"===t.type&&u.hasDateFormat(t),isNumber:t=>"number"===t.type||u.isInteger(t),isObject:t=>"object"===t.type,isRequired:t=>t.required},d={getProps:t=>t&&t.fields,getType:t=>t&&t.type,getName:t=>t&&(t.name||t.title),getConstraints:t=>t,isString:t=>t&&"string"===t.type,isArray:t=>t&&"array"===t.type,isInteger:t=>t&&"int"===t.type,isFloat:t=>t&&"float"===t.type,isDouble:t=>t&&"double"===t.type,isBoolean:t=>t&&"boolean"===t.type,isDate:t=>t&&"int"===t.type&&"date"===t.logicalType,isNumber:t=>t&&(d.isInteger(t)||d.isFloat(t)||d.isDouble(t)),isObject:t=>t&&"record"===t.type,isRequired:t=>t&&t.required},p={"json-schema":c,"type-def":u,avro:d};class g extends class{constructor(t={}){this.config=t;const{log:e,error:s}=t,r=t.enable||{};!0===t.logging&&(r.log=!0),!1===t.logging&&(r.log=!1),this.enable=r,this.log="function"==typeof e?e:console.log,this.err="function"==typeof s?s:console.error}error(t){var e=[].slice.call(arguments,1);if(!1!==this.enable.error&&this.err)throw e&&e.length?this.err(t,...e):this.err(t),t}warn(t){this.enable.warn&&this.logInfo("WARNING: "+t,...[].slice.call(arguments,1))}logTypeInfo(t){if(!this.enable.log)return;if(!this.log)return;const e=this.config.logTypes||[];e.length&&e.find(t=>this.type===t)&&logInfo(t,...[].slice.call(arguments,1))}logDetails(t,e){const s=this.config.logDetailed||[];s.length&&s.find(t=>!(t.key&&e.key!==t.key||t.constraintName&&e.constraintName!==t.constraintName||t.propName&&e.propName!==t.propName||t.method&&e.method!==t.method))&&this.logInfo(t,e,...[].slice.call(arguments,2))}logInfo(t){var e=[].slice.call(arguments,1);this.enable.log&&this.log&&(e&&e.length?this.log(t,...e):this.log(t))}}{constructor(t={}){super(t)}isNothing(t){return null==t}isPresent(t){return!this.isNothing(t)}hasKey(t,e){if(this.isObjectType(t))return Object.keys(t).includes(e)}toNumber(t){return Number(t)}isNumberLike(t){return!isNaN(this.toNumber(t))}isObjectType(t){return t===Object(t)}isArrayType(t){return Array.isArray(t)}isNumberType(t){return!isNaN(t)}isStringType(t){return"string"==typeof t}isFunctionType(t){return"function"==typeof t}isDateType(t){return t instanceof Date}}class y{constructor(t,e){this.schemaParserMap=t,this.name=e}lookup(t=this.name){return this.schemaParserMap[t]}build(){const t=this.lookup();if(t.extends){const e=this.extend(t.extends);if(e)return e}return t}extend(t){const e=this.lookup(t);e&&(entry={...e,...this.lookup()})}}class m extends g{constructor(t={}){super(t);const e=(t.createSchemaParserBuilder||new y(t.schemaParserMap||p,t.schemaType||"json-schema")).build();this.config={...e,...t}}createSchemaParserBuilder(t,e){return new SchemaParserBuilder(t,e)}}function f(t){return t===Object(t)}class b{constructor(t,e={}){this.whenEntryObj=t;const{schema:s,properties:r,config:i,key:n,when:a,type:o}=e;this.schema=s,this.when=a,this.properties=r||{},this.key=n,this.type=o,this.config=i}validateAndConfigure(t){if(!f(t=t||this.whenEntryObj))return this.warn("invalid or missing when entry constraint object",t),!1;const e=Object.keys(t);return e.length<2?(this.warn(`validateAndConfigure: when entry constraint must have at least 2 keys: ${e}`,t),!1):this.hasKey(e,"is")?!!this.hasKey(e,"then")||(this.warn(`validateAndConfigure: when entry constraint missing 'then' or 'else' constraint: ${e}`,t),!1):(this.warn(`validateAndConfigure: when entry constraint missing 'is' constraint: ${e}`,t),!1)}createYupSchemaEntry(t){return this.config.createYupSchemaEntry(t)}createValue(t,e){return"string"==typeof t&&(t={[t]:!0}),f(t)||this.error(`createValue: ${e} must be a schema object`),{key:this.key,type:this.type,...t}}createEntryOpts(t,e){const s=this.createValue(t,e);return{schema:this.schema,properties:this.properties,key:this.key,type:this.type,value:s,config:this.config}}createEntry(t,e){const s=this.createEntryOpts(t,e);return this.createYupSchemaEntry(s)}hasKey(t,e){return t.find(t=>t===e)}hasAnyKey(t,e){return t.find(t=>e.includes(t))}whenEntryFor(t,e,s){if(s=s||e,"string"==typeof t&&(t={[t]:!0}),!f(t))throw`whenEntryFor: Invalid when object ${t}`;const r={...t[s]};return delete t[s],r?(t[e]=this.createEntry(r,e),t):t}calcEntryObj(){let t={...this.whenEntryObj};return t=this.whenEntryFor(t,"then"),"otherwise"in t&&(t=this.whenEntryFor(t,"otherwise")),"else"in t&&(t=this.whenEntryFor(t,"else")),t}get entryObj(){return this.validateAndConfigure()&&this.calcEntryObj()}warn(t,e){console.error("[WhenEntry] WARNING",t,e)}error(t,e){throw console.error("[WhenEntry] ERROR",t,e),t}}function v(t){return t===Object(t)}class C{constructor(t={}){const{type:e,key:s,value:r,when:i,schema:n,properties:a,config:o}=t;this.opts=t,this.when=i,this.key=s,this.type=e,this.value=r,this.schema=n,this.properties=a,this.config=o,this.validate()}validate(){"string"!=typeof this.type&&this.error(`validate: invalid or mising type: ${this.type}`,this.opts),v(this.when)||this.error(`validate: invalid or mising when: ${this.when}`,this.opts)}validateAndConfigure(t){if(!v(t=t||this.when))return this.warn("invalid or missing when constraint",t),!1;const e=Object.keys(t);return e.length<1?(this.warn(`when constraint must have at least 1 key: ${e}`,t),!1):(this.whenKeys=e,!0)}createWhenEntry(t,e){return((t,e={})=>new b(t,e))(t,e)}accumulate(t,e){let s=this.when[e];if(!v(s))return this.warn(`invalid when entry constraint object ${s} for ${e}`),t;const r={type:this.type,key:this.key,schema:this.schema,properties:this.properties,config:this.config},{entryObj:i}=this.createWhenEntry(s,r);return i?t=Object.assign(t,i):t}get constraintObj(){return this.whenKeys?this.whenKeys.reduce(this.accumulate.bind(this),{}):{}}get keyVal(){const t=this.whenKeys||[];return 1===t.length?t[0]:t}get constraintValue(){return!!this.keyVal&&[this.keyVal,this.constraintObj]}get constraint(){return this.validateAndConfigure()&&this.constraintValue}warn(t,e){console.error("[WhenCondition] WARNING",t,e)}error(t,e){throw console.error("[WhenCondition] ERROR",t,e),t}}const w=t=>new C(t);class E extends g{constructor(t,e={}){super(e),this.typeHandler=t,this.type=t.type,this.builder=t.builder,this.constraintsAdded={},this.delegators.map(e=>{this[e]=t[e]})}get delegators(){return["errMessages","base","key","type","constraints","errorMessageHandler","logInfo","warn"]}build(t,e={}){let{constraintName:s,constraintValue:r,propValue:i,method:n,yup:a,value:o,values:h,errName:l}=e;if(a=a||this.base,r=this.getFirstValue([r,i,this.constraints[t]]),s=s||t,n=n||s,this.idObj={propName:t,method:n,constraintName:s,key:this.key},this.logDetailed("build",e,{resolved:{constraintValue:r,constraintName:s}}),this.isNothing(r))return this.warn("no prop value",{constraintValue:r}),!1;const c=this.aliasMap[n]||n;if(!a[c])return this.warn(`Yup has no such API method: ${c}`),!1;const u=a[c].bind(a),d=this.validationErrorMessage(s),p=l&&this.validationErrorMessage(l),g={constraintName:s,yup:a,constraintFn:u,errFn:d||p},y=["multiValueConstraint","presentConstraintValue","nonPresentConstraintValue"];let m;const f=this.type;for(let t of y)if(m=this[t].bind(this)(this.getFirstValue([o,h,r],{constraintName:s,type:f}),g),m)break;return m?(this.base=m,m):(this.warn("buildConstraint: missing value or values options"),!1)}yupRefMap(){return{string:["length","min","max"],number:["min","max","lessThan","moreThan"],date:["min","max"],array:["length","min","max"]}}getFirstValue(t,e={}){const{constraintName:s,type:r}=e,i=this.isPresent.bind(this),n=this.yupRefMap[r],a=t.filter(i)[0];return n&&n.includes(s)&&this.isStringType(a)?Yup.ref(a):a}nonPresentConstraintValue(t,{constraintName:e,constraintFn:s,errFn:r}){if(!this.isPresent(t))return this.logInfo("nonPresentConstraintValue",{constraintValue:t}),this.onConstraintAdded({method:"nonPresentConstraintValue",name:e}),s(r)}presentConstraintValue(t,{constraintName:e,constraintFn:s,errFn:r}){if(this.isPresent(t))return this.logInfo("presentConstraintValue",{constraintName:e,constraintValue:t}),this.onConstraintAdded({method:"presentConstraintValue",name:e,value:t}),this.isNoValueConstraint(e)?(this.logInfo("isNoValueConstraint",{constraintName:e}),s(r)):(this.logInfo("presentConstraintValue: apply validator function",{constraintName:e,constraintValue:t}),s(t,r));this.logInfo("presentConstraintValue: value not present",{constraintName:e,constraintValue:t})}multiValueConstraint(t,{constraintFn:e,constraintName:s,errFn:r}){if(this.isPresent(t)){if(this.logInfo("multiValueConstraint",{constraintName:s,values:t}),Array.isArray(t))return this.onConstraintAdded({method:"multiValueConstraint",name:s,value:t}),this.logInfo("multiValueConstraint: apply validator function",{constraintName:s,value:t}),this.callConstraintFn(e,s,t,r);this.warn("buildConstraint: values option must be an array of arguments")}}callConstraintFn(t,e,s,r){return this.isMultiArgsCall(e)?t(...s,r):t(s,r)}isMultiArgsCall(t){return this.multiArgsValidatorMethods[t]}get multiArgsValidatorMethods(){return this.config.multiArgsValidatorMethods||{when:!0}}isNoValueConstraint(t){return this.noValueConstraints.includes(t)}get noValueConstraints(){return["required","email","url","format"]}addTrueValueConstraint(t,{constraintName:e,errName:s}={}){return this.addConstraint(t,{constraintName:e,value:!0,errName:s})}addConstraint(t,e){const s=this.build(t,e);return!!s&&(this.typeHandler.base=s,s)}onConstraintAdded({method:t,name:e,value:s}){if(this.constraintsAdded[e]=s,this.builder)return this.builder.onConstraintAdded({type:this.type,method:t,name:e,value:s}),this.typeHandler;this.logInfo("no builder set to notify in ConstraintBuilder")}get constraintsMap(){return{simple:["required","notRequired","nullable"],value:["default","strict"]}}logDetailed(t){this.logDetails(t,this.idObj,...[].slice.call(arguments,1))}validationErrorMessage(t){return this.errorMessageHandler.validationErrorMessage(t)}get aliasMap(){return{oneOf:"oneOf",enum:"oneOf",anyOf:"oneOf"}}}class T extends g{constructor(t,e={}){super(e),this.typeHandler=t,this.init()}init(){const{typeHandler:t}=this;this.constraints=t.constraints,this.errMessages=t.errMessages,this.key=t.key,this.type=t.type,this.description=t.description,this.title=t.title,this.setErrMessage()}errMessageMap(t={}){return t[this.errMessagesMapKey]||this.errMessages}get errMessageKey(){return this.config.errMessageKey||"errMessage"}get errMessagesMapKey(){return this.config.errMessagesMapKey||"errMessages"}setErrMessage(){const{typeHandler:t}=this,{value:e}=t;if(!e.errMessage)return;const s=this.errMessageKey,r=this.errMessageMap(e);return r[this.key]=e[s]||r[this.key],this}validationErrorMessage(t){const{constraints:e,description:s,title:r}=this,i=this.errMessageFor(t);return"function"==typeof i?i(e,{description:s,title:r}):i}errMessageFor(t){const{errMessages:e,key:s}=this,r=e[s];return r?r[t]:e[`$${t}`]}}class N extends Error{}class O extends m{constructor(t={}){super(t.config),this.init(t)}init(t){let{schema:e,key:s,value:r,config:i,entryHandler:n}=t;i=i||{},e=e||{},this.validateOnCreate(s,r,t),this.opts=t,this.entryHandler=n,this.validator=this.getValidator(),this.key=s,this.schema=e,this.properties=e.properties||{},this.value=r,this.title=r.title,this.description=r.description,this.constraints=this.getConstraints(),this.format=r.format||this.constraints.format,this.config=i||{},this.type=this.baseType,this.mixedConfig=this.config.mixedEnabled||{},this.typeConfig=this.config[this.type]||{},this.errMessages=i.errMessages||{},this.configureTypeConfig(),this.constraintsAdded={},this.base=this.getBase()}get builder(){return this.entryHandler&&this.entryHandler.builder}getBase(){return this.customBaseValidator||this.validatorInstance}get customBaseValidator(){return this.config.validatorFor&&this.config.validatorFor(this.type)}getValidator(){return this.opts.validator||this.config.validator||this.builder&&this.builder.validator||a}get baseType(){return"mixed"}get validatorInstance(){return this.validator.mixed()}configureTypeConfig(){this.typeConfig.enabled||this.typeConfig.extends||this.typeConfig.convert&&(this.typeConfig.extends=Object.keys(this.typeConfig.convert))}isRequired(t){return!0===(t=t||this.value).required}get mode(){return this.config.mode||{}}get disableFlags(){return[!1,"disabled","no","off"]}get enableFlags(){return[!0,"enabled","yes","on"]}disabledMode(t){const e=this.mode[t];return!!this.disableFlags.find(t=>e===t)}enabledMode(t){const e=this.mode[t];return!!this.enableFlags.find(t=>e===t)}get shouldPreProcessValue(){return!this.disabledMode("notRequired")}preProcessedConstraintValue(t){return this.shouldPreProcessValue?this.isRequired(t)?t:{...t,notRequired:!0}:t}set value(t){this._value=this.preProcessedConstraintValue(t)}get value(){return this._value}initHelpers(){const{config:t}=this;this.errorMessageHandler=(this.config.createErrorMessageHandler||this.createErrorMessageHandler)(this,t),this.constraintBuilder=(this.config.createConstraintBuilder||this.createConstraintBuilder)(this,t),this.rebind("addConstraint","addTrueValueConstraint")}createConstraintBuilder(t,e={}){return new E(t,e)}createErrorMessageHandler(t,e={}){return new T(t,e)}rebind(){[].slice.call(arguments).map(t=>{const e=this[t];this[t]=this.isFunctionType(e)?e.bind(this):e})}validateOnCreate(t,e,s){t||this.error(`create: missing key ${JSON.stringify(s)}`),e||this.error(`create: missing value ${JSON.stringify(s)}`)}get mixedEnabled(){return this.mixedConfig.enabled||["oneOf","notOneOf","when","nullable","isType","label","const","refValueFor"]}get typeEnabled(){return[]}get $typeExtends(){if(Array.isArray(this.typeConfig.extends))return o.default([...this.typeConfig.extends,...this.typeEnabled])}get configuredTypeEnabled(){return Array.isArray(this.typeConfig.enabled)?this.typeConfig.enabled:this.typeEnabled}get $typeEnabled(){return this.$typeExtends||this.configuredTypeEnabled}get enabled(){return[...this.mixedEnabled,...this.$typeEnabled]}convertEnabled(){this.enabled.map(t=>{const e=this.convertFnFor(t);e&&e(this)})}convertFnFor(t){return this.customConvertFnFor(t,this)||this.builtInConvertFnFor(t)}customConvertFnFor(t){return(this.typeConfig.convert||{})[t]}builtInConvertFnFor(t){return this[t].bind(this)}getConstraints(){return this.config.getConstraints(this.value)}createSchemaEntry(){return this.convert().base}convert(){return this.initHelpers(),this.addMappedConstraints(),this.convertEnabled(),this}apply(t){var e=[].slice.call(arguments,1);if("string"!=typeof t)throw new TypeError("[Mixed] apply must take a method name available on the validator instance as first argument");return this.base=e&&e.length&&this.base[t](...e)||this.base,this}applyArr(t,e){if("string"!=typeof t)throw new TypeError("[Mixed] apply must take a method name available on the validator instance as first argument");return this.base=e&&e.length&&this.base[t](e)||this.base,this}addTrueValueConstraint(t,e){const s=this.constraintBuilder.addTrueValueConstraint(t,e);if(s){const{base:t}=s;this.base=t}return this}addConstraint(t,e){if(!this.constraintBuilder)throw new Error(`[YupMixed] addConstraint: Missing constraintBuilder in ${this.constructor.name}`);const s=this.constraintBuilder.addConstraint(t,e);return s&&(this.base=s),this}addMappedConstraints(){const t=Object.keys(this.constraintsMap),e=this.addMappedConstraint.bind(this);return t.map(e),this}addMappedConstraint(t){const{constraintsMap:e}=this,s=this["trueValue"===t?"addTrueValueConstraint":"addConstraint"],r=this.constraints[t];e[t].map(t=>{s(t,{value:r})})}get constraintsMap(){return{simple:["default","required","notRequired","nullable"],trueValue:["strict"]}}refValueFor(){let t=this.constraints.refValueFor;return this.isNothing(t)?this:(this.logInfo("refValueFor",{propRefName:t}),this.apply("when",(e,s)=>e?s.required().oneOf([a.ref(t)]):s))}normalizeValues(t){return Array.isArray(t)?t:[t]}get oneOfValues(){return this.constraints.enum||this.constraints.oneOf||this.constraints.anyOf}get oneOfAliases(){return["oneOf","enum","anyOf"]}get oneOfAlias(){return this.oneOfAliases.find(t=>void 0!==this.constraints[t])}oneOf(){let t=this.oneOfValues;if(this.isNothing(t))return this;t=this.normalizeValues(t);const e=this.resolveValues(t),s=this.oneOfAlias;return this.logDetails("type",{constraintName:s,method:"oneOf",key:this.key,type:this.type},t,e),this.addConstraint(s,{values:e})}logDetailed(t,e){this.logDetails(t,e,...[].slice.call(arguments,2))}get notOneOfValues(){const{not:t,notOneOf:e}=this.constraints;return e||t&&(t.enum||t.oneOf)}notOneOf(){let t=this.oneOfValues;if(this.isNothing(t))return this;t=this.normalizeValues(t);const e=this.resolveValues(t);return this.logDetails("type",{constraintName:"notOneOf",method:"notOneOf",key:this.key,type:this.type},t,e),this.addConstraint("notOneOf",{values:e})}resolveValues(t){return t.map(t=>this.isObjectType(t)?this.resolveValue(t):t)}const(){let t=this.constraints.const;if(this.isNothing(t))return this;if(this.isDataRef(t)){const e=this.normalizeDataRefPath(t);t=a.ref(e)}return this.addConstraint("const",{value:t})}normalizeDataRefPath(t){return(t=t.$data||t).split("/").shift().join("/")}isDataRef(t){return this.isPresent(t.$data)}isConst(t){return this.hasKey(t,"const")}resolveValue(t){return this.isConst(t)?t.const:(0,this.config.createYupSchemaEntry)({schema:this.schema,key:this.key,value:t,config:this.config})}validationErrorMessage(t){const e=this.errorMessageHandler.validationErrorMessage.bind(this.errorMessageHandler);return(this.config.validationErrorMessage||e)(t,this)}createWhenConditionFor(t){return(this.config.createWhenCondition||w)({key:this.key,type:this.type,value:this.value,schema:this.schema,properties:this.properties,config:this.config,when:t})}label(){const t=this.value,e=t.title||t.label;return this.base=e&&this.base.label(e)||this.base,this}when(){const t=this.constraints.when;if((e=t)!==Object(e))return this;var e;const{constraint:s}=this.createWhenConditionFor(t);return s?(this.logInfo(`Adding when constraint for ${this.key}`,s),this.addConstraint("when",{values:s,errName:"when"}),this):(this.warn(`Invalid when constraint for: ${t}`),this)}isType(){return this.addConstraint("isType",{value:this.constraints.isType,errName:"notOneOf"}),this}nullable(){const{nullable:t,isNullable:e}=this.constraints;return this.addConstraint("nullable",{value:t||e,errName:"notOneOf"}),this}message(){return config.messages[this.key]||config.messages[this.type]||{}}errMessage(t="default"){return this.message[t]||"error"}toValidJSONSchema(){}normalize(){}deNormalize(){}errorMsg(t){this.throwError(t)}error(t,e){const s=[`[${t}]`,e].join(" ");this.errorMsg(s)}throwError(t){throw t}}const x=["oneOf","enum","required","notRequired","minDate","min","maxDate","max","trim","lowercase","uppercase","email","url","minLength","maxLength","pattern","matches","regex","integer","positive","minimum","maximum"],M={errMessages:(t=x)=>t.reduce((t,e)=>(t[e]=({key:t,value:e})=>`${t}: invalid for ${e.name||e.title}`,t),{})};class V extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance,this.createYupSchemaEntry=this.config.createYupSchemaEntry}get baseType(){return"array"}get validatorInstance(){return this.validator.array()}static create(t){return new V(t)}convert(){return super.convert(),this}get typeEnabled(){return["maxItems","minItems","ensureItems","compact","itemsOf"]}ensureItems(){return this.addConstraint("ensure")}compact(){return this.addConstraint("compact")}itemsOf(){const{items:t,itemsOf:e}=this.constraints,s=t||e||this.constraints.of;if(!this.isNothing(s))if(Array.isArray(s))this.error("itemsOf","does not (yet) support an Array of schemas");else if(this.isObjectType(s)){if(this.createYupSchemaEntry){try{const t=s,e={key:this.key,value:t,config:this.config};this.logTypeInfo("array:of",{schemaConf:e});const r=this.createYupSchemaEntry(e);return this.logTypeInfo("array:of",{schemaEntry:r}),this.addConstraint("of",{constraintValue:r,propValue:t,value:r})}catch(t){this.error("itemsOf: Error",t)}return this}this.warn("missing createYupSchemaEntry in config, needed for recursive validation")}else this.error("itemsOf","must be a schema object, was "+typeof s)}maxItems(){const{maxItems:t,max:e}=this.constraints,s=t||e;if(!this.isNumberType(s))return this;if(!this.isValidSize(s))return this.handleInvalidSize("maxItems",s);const r=s&&this.base.max(s);return this.base=r||this.base,this}minItems(){const{minItems:t,min:e}=this.constraints,s=t||e;if(!this.isNumberType(s))return this;if(!this.isValidSize(s))return this.handleInvalidSize("minItems",s);const r=s&&this.base.min(s);return this.base=r||this.base,this}$items(){return this}$additionalItems(){return this}$uniqueItems(){return this}$contains(){return this}handleInvalidSize(t,e){const s=`invalid array size constraint for ${t}, was ${e}. Must be a number >= 0`;return this.config.warnOnInvalid?(this.warn(s),this):(this.error(s,e),this)}isValidSize(t){return this.isNumberType(t)&&t>=0}}class k extends m{constructor(t){super(t)}isArray(t){return this.config.isArray||this.error("ArrayHandler: missing isArray in config",this.config),this.config.isArray(t)}handle(t){return this.isArray(t)&&V.create(t).createSchemaEntry()}}function S(t,e={}){return t&&new k(e).handle(t)}class I extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance}get baseType(){return"boolean"}get validatorInstance(){return this.validator.boolean()}static create(t){return new I(t)}}class j{constructor(t){this.config=t}isBoolean(t){return this.config.isBoolean(t)}handle(t){return this.isBoolean(t)&&I.create(t).createSchemaEntry()}}function A(t,e={}){return t&&new j(e).handle(t)}class D extends g{constructor(t,e){super(t.config),this.map=e||this.$map||{},this.typeHandler=t,this.delegates.map(e=>{const s=t[e];s||this.error(`missing delegate: ${e}`,{typeHandler:t}),this[e]=this.isFunctionType(s)?s.bind(t):s})}isStringType(t){return"string"==typeof t}get delegates(){return["constraints","addConstraint","constraintsAdded"]}add(){const t=this.map;Object.keys(t).map(e=>{const s=this.entryNames(t[e]);this.addConstraints(e,s)})}entryNames(t){return Array.isArray(t)?t:[t]}addConstraints(t,e=[]){return e.map(e=>{const s=this.validateAndTransform(e);this.addConstraint(e,{method:t,value:s})}),this}validateAndTransform(t){const e=this.constraints[t];return this.validate(t,e),this.transform(e)}invalidMsg(t,e){return`invalid constraint for ${t}, was ${e}.`}get explainConstraintValidMsg(){return""}invalidConstraintMsg(t,e){return[this.invalidMsg(t,e),this.explainConstraintValidMsg].join("\n")}validate(t,e){return this.isNothing(e)?this:this.isValidConstraint(e)?void 0:this.handleInvalidConstraint(t,e)}isValidConstraint(t){return!0}handleInvalidConstraint(t,e){const s=this.invalidConstraintMsg(t,e);return this.config.warnOnInvalid?(this.warn(s),this):(this.error(s,e),this)}}class P extends D{constructor(t){super(t)}transform(t){return this.typeHandler.toNumber(t)}isValidConstraint(t){return this.typeHandler.isNumberLike(t)||this.typeHandler.isStringType(t)}get explainConstraintValidMsg(){return"Must be a number or convertible to a number"}}class F extends P{constructor(t){super(t)}get $map(){return{moreThan:["exclusiveMinimum","moreThan"],lessThan:["exclusiveMaximum","lessThan"],max:["maximum","max"],min:["minimum","min"]}}}class R extends m{constructor(t,e){super(e),this.obj=t}isValid(){return!1}verify(){return this.isPresent(this.obj)&&this.isValid(this.obj)}}class H extends R{constructor(t,e){super(t,e)}isValid(){return this.config.isNumber(this.obj)}}const $=(t,e={})=>function(t,e){return new H(t,e)}(t,e).verify();function Y(t,e={}){return $(t,e)&&function(t){return q.schemaEntryFor(t)}(t)}class q extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance,this.rangeConstraint=new F(this)}get baseType(){return this.normalizeNumType(this.opts.type)}get validatorInstance(){return this.validator.number()}normalizeNumType(t){return"int"===t?"integer":t}static create(t){return new q(t)}static schemaEntryFor(t){return q.create(t).createSchemaEntry()}get typeEnabled(){return["range","posNeg","integer"]}convert(){return super.convert(),this}range(){this.rangeConstraint.add()}truncate(){return this.addConstraint("truncate")}round(){const{round:t}=this.constraints;if(this.isNothing(t))return this;const e=this.isStringType(t)?t:"round";return t&&this.base.round(e),this}posNeg(){this.positive(),this.negative()}integer(){return this.isInteger&&this.addConstraint("integer"),this}get isInteger(){return this.config.isInteger(this.type)}positive(){return this.addConstraint("positive")}negative(){return this.addConstraint("negative")}get isNegative(){const{exclusiveMaximum:t,negative:e}=this.constraints;return!!e||void 0!==t&&0===t}get isPositive(){const{exclusiveMinimum:t,positive:e}=this.constraints;return!!e||void 0!==t&&0===t}normalize(){this.constraints.maximum=this.constraints.maximum||this.constraints.max,this.constraints.minimum=this.constraints.minimum||this.constraints.min}}class B extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance,this.properties=this.value.properties}get baseType(){return"object"}get validatorInstance(){return this.validator.object()}static create(t){return new B(t)}get typeEnabled(){return["noUnknown","camelCase","constantCase"]}convert(){if(!this.properties)return this;super.convert();const t=this.value,e=this.config;if(t){e.buildYup||this.error("convert","Missing buildYup function from config",e);const s=this.config.buildYup(t,e);this.base=s}return this}camelCase(){return this.addConstraint("camelCase")}constantCase(){return this.addConstraint("constantCase")}noUnknown(){const{noUnknown:t,propertyNames:e}=this.value,s=t||e,r=s&&this.base.noUnknown(s,this.validationErrorMessage("propertyNames")||this.validationErrorMessage("noUnknown"));return this.base=r||this.base,this}}const z=t=>t&&"object"===t.type;class K{constructor(t={}){(t=t||{}).isObject=t.isObject||z,this.config=t,this.schema=t.schema}isObject(t){return this.config.isObject(t.value)}handle(t){return this.isObject(t)&&B.create({...t,config:this.config}).createSchemaEntry()}}function L(t,e={}){return t&&new K(e).handle(t)}class U extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance}get baseType(){return"string"}get validatorInstance(){return this.validator.string()}static create(t){return new U(t)}convert(){return super.convert(),this}get typeEnabled(){return["normalize","minLength","maxLength","pattern","lowercase","uppercase","email","url","genericFormat"]}trim(){return this.addConstraint("trim")}lowercase(){return this.addConstraint("lowercase")}uppercase(){return this.addConstraint("uppercase")}genericFormat(){1!=!this.config.format&&this.validator.prototype[this.format]&&this.addConstraint(this.format)}email(){if(!this.isEmail)return this;const t=this.constraintNameFor("email","format"),e="email";return this.addConstraint("email",{constraintValue:!0,constraintName:t,method:e,errName:e}),this}constraintNameFor(){return[].slice.call(arguments).find(t=>this.constraints[t])}get isEmail(){return this.constraints.email||"email"===this.format}url(){if(!this.isUrl)return this;const t=this.constraintNameFor("url","format");return this.addConstraint("url",{constraintValue:!0,constraintName:t,method:"url",errName:"url"}),this}get isUrl(){return this.constraints.url||"url"===this.format}minLength(){const{minLength:t}=this.constraints,e=this.validationErrorMessage("minLength")||this.validationErrorMessage("min"),s=t&&this.base.min(t,e);return this.base=s||this.base,this}maxLength(){const{maxLength:t}=this.constraints,e=this.validationErrorMessage("maxLength")||this.validationErrorMessage("max"),s=t&&this.base.max(t,e);return this.base=s||this.base,this}pattern(){const{pattern:t,flags:e,excludeEmptyString:s}=this.constraints;if(!t)return this;const r=new RegExp(t,e),i=this.validationErrorMessage("pattern")||this.validationErrorMessage("matches")||this.validationErrorMessage("regex"),n=r&&this.base.matches(r,{message:i,excludeEmptyString:s});return this.base=n||this.base,this}normalize(){this.constraints.pattern=this.constraints.pattern||this.constraints.matches||this.constraints.regex,this.constraints.maxLength=this.constraints.maxLength||this.constraints.max,this.constraints.minLength=this.constraints.minLength||this.constraints.min}}class W{constructor(t){this.config=t}isString(t){return this.config.isString(t)}handle(t){return this.isString(t)&&U.create({config:this.config,...t}).createSchemaEntry()}}function _(t,e={}){return t&&new W(e).handle(t)}class J extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance}get baseType(){return"date"}get validatorInstance(){return this.validator.date()}static create(t){return new J(t)}get typeEnabled(){return["minDate","maxDate"]}convert(){return super.convert(),this}toDate(t){return new Date(t)}isValidDateType(t){return this.isStringType(t)||this.isDateType(t)}isValidDate(t){return!!this.isValidDateType(t)&&(!this.isStringType(t)||Boolean(Date.parse(t)))}transformToDate(t){return this.isNumberType(t)?new Date(t):t}minDate(){const t=this.constraints.minDate||this.constraints.min;if(this.isNothing(t))return this;const e=this.transformToDate(t);if(!this.isValidDateType(e))return this.handleInvalidDate("minDate",e);const s=e&&this.base.min(this.toDate(e),this.validationErrorMessage("minDate")||this.validationErrorMessage("min"));return this.base=s||this.base,this}maxDate(){const t=this.constraints.maxDate||this.constraints.max;if(this.isNothing(t))return this;const e=this.transformToDate(t);if(!this.isValidDateType(e))return this.handleInvalidDate("maxDate",e);const s=e&&this.base.max(this.toDate(e),this.validationErrorMessage("maxDate")||this.validationErrorMessage("max"));return this.base=s||this.base,this}handleInvalidDate(t,e){const s=`invalid constraint for ${t}, was ${e}. Must be a number, string (valid date format) or a Date instance`;return this.config.warnOnInvalid?(this.warn(s),this):(this.error(s,e),this)}}class G{constructor(t){this.config=t}isDate(t){return this.config.isDate(t)}handle(t){return this.isDate(t)&&J.create(t).createSchemaEntry()}}function Q(t,e={}){return t&&new G(e).handle(t)}var X={__proto__:null,errValKeys:x,defaults:M,YupArray:V,toYupArray:S,YupBoolean:I,toYupBoolean:A,YupNumber:q,toYupNumberSchemaEntry:Y,toYupNumber:function(t,e={}){return $(t,e)&&function(t){return q.create(t)}(t)},YupObject:B,toYupObject:L,YupString:U,toYupString:_,YupDate:J,toYupDate:Q,YupMixed:O,ConvertYupSchemaError:N,Base:m};class Z extends Error{}class tt extends m{constructor(t,e,s){super(e);const{value:r,type:i,kind:n,name:a,key:o,schema:h,types:l}=t;this.entryHandler=s||t.entryHandler,this.builder=t.builder,this.opts=t,this.kind=n,this.value=r,this.schema=h,this.key=o,this.value=r||{},this.name=a,this.type=i,this.types=l}get validator(){return this.builder.validator}error(t,e){let{opts:s}=this;throw s=s||{},s=e?{data:e,...s}:s,console.error(t,...s),new Z(t)}resolve(){throw"Must be implemented by subclass"}get obj(){const{schema:t,key:e,value:s,type:r,kind:i,config:n,entryHandler:a}=this;return{schema:t,key:e,value:s,type:r,kind:i,config:n,entryHandler:a}}}class et extends tt{constructor(t,e,s){super(t,e,s)}resolve(){const{value:t}=this;if(!Array.isArray(t))return;const e=this.config.toMultiType;return e?e(this):this.oneOf()}oneOf(){const t=this.value,e=this.createEntry.bind(this),s=t.map(e);return this.mixed().oneOf(s)}notOneOf(){const t=this.value,e=this.createEntry.bind(this),s=t.map(e);return this.mixed().notOneOf(s)}createEntry(t){const{createYupSchemaEntry:e}=this.config;return t=normalizedValue(t),e({schema:this.schema,key:this.key,value:t,config:this.config})}normalizedValue(t){return"string"==typeof t?{type:t}:t}mixed(){return this.validator.mixed()}}class st extends tt{constructor(t,e,s){super(t,e,s)}resolve(){const{value:t}=this;if(Array.isArray(t))return;const e=this.config.toSingleType;if(e)return e(this);const{obj:s,config:r,entryHandler:i}=this,n=Object.keys(this.types);let a;for(let t of n){const e=this.types[t];if(e&&(a=e(s,r,i)),a)break}return a}}const rt=(t,e,s)=>new it(t,e,s);class it extends tt{constructor(t,e,s){super(t,e,s),this.initResolvers()}initResolvers(){const{opts:t,config:e,entryHandler:s}=this,r=e.createMultiTypeResolver||this.createMultiTypeResolver.bind(this);this.multiTypeResolver=r(t,e,s);const i=e.createSingleTypeResolver||this.createSingleTypeResolver.bind(this);this.singleTypeResolver=i(t,e,s)}createMultiTypeResolver(){const{opts:t,config:e,entryHandler:s}=this;return new et(t,e,s)}createSingleTypeResolver(){const{opts:t,config:e,entryHandler:s}=this;return new st(t,e,s)}resolve(){return this.toMultiType()||this.toSingleType()||this.toDefaultEntry()}toMultiType(){return(this.config.toMultiType||this.singleTypeResolver.resolve.bind(this.singleTypeResolver))(this)}toSingleType(){return(this.config.toSingleType||this.singleTypeResolver.resolve.bind(this.singleTypeResolver))(this)}toDefaultEntry(){return this.defaultType()}defaultType(){this.error("toEntry: unknown type",this.type)}}class nt extends Error{}class at extends m{constructor(t){super(t.config);const{schema:e,name:s,key:r,value:i,config:n,builder:a}=t;this.builder=a,this.opts=t,this.schema=e,this.key=r,this.value=i||{},this.config=n||{},this.name=s,this.init()}get calcType(){const{value:t}=this;return Array.isArray(t)?"array":t.type}get calcKind(){return"array"===this.type?"multi":"single"}createNew(t){return new at(t).toEntry()}init(){this.type=this.calcType,this.kind=this.calcKind,this.setTypeHandlers(),this.setPropertyHandler()}get validator(){return this.builder&&this.builder.validator}setPropertyHandler(){const{config:t}=this;this.propertyValueHandler=(t.createPropertyValueHandler||this.createPropertyValueHandler)(this.propertyHandlerOpts,t)}get propertyHandlerOpts(){const{types:t,value:e,name:s,key:r,type:i,kind:n,schema:a}=this;return{type:i,kind:n,types:t,value:e,name:s,key:r,schema:a,entryHandler:this}}createPropertyValueHandler(t,e){return rt(t,e,this)}get defaultTypeHandlerMap(){return{string:_,number:Y,boolean:A,array:S,object:L,date:Q}}setTypeHandlers(){this.types=this.config.types||this.typeHandlers}get typeHandlers(){return{...this.defaultTypeHandlerMap,...this.config.typeHandlers||{}}}isValidSchema(){const{type:t}=this;return this.isStringType(t)}error(t,e){const{opts:s}=this;throw e?console.error(t,e,...s):console.error(t,...s),new nt(t)}toEntry(){if(!this.isValidSchema()){const t=JSON.stringify(this.schema);this.error(`Not a valid schema: type ${this.type} must be a string, was ${typeof this.type} ${t}`)}const{opts:t,config:e}=this;return this.propertyValueHandler.resolve(t,e)}}function ot(t={}){return new at(t).toEntry()}function ht(t,e={}){return new ct(t,{...e}).yupSchema}function lt(t){return t===Object(t)}class ct extends m{constructor(t,e={}){super(e),this.init(t,e)}init(t,e){e.buildYup=ht,e.createYupSchemaEntry=e.createYupSchemaEntry||ot,this.config=Object.assign(this.config,e),this.schema=t;const s=this.getType(t),r=this.getProps(t);if(this.type=s,this.properties={...r},this.additionalProps=this.getAdditionalProperties(t),this.required=this.getRequired(t),this.setLocale(),("function"==typeof e.init?e.init:()=>{}).bind(this)(t,e),!function(t){return t&&"object"===t}(s))return void this.error(`invalid schema: must be type: "object", was type: ${s}`);if(!lt(r)){const t=JSON.stringify(n);return void this.error(`invalid schema: must have a properties object: ${t}`)}const i=this.getName(t),n=(e.buildProperties||this.buildProperties).bind(this)(t,this),a=this.propsToShape({properties:n,name:i,config:e});this.shapeConfig=a,this.validSchema=!0}get validator(){return a}setLocale(){this.config.locale&&a.setLocale(this.config.locale)}getAdditionalProperties(t){return t.additionalProperties}getRequired(t){const{getRequired:e}=this.config;return e?e(t):t.required||[]}getProps(t){return this.config.getProps(t)}getType(t){return this.config.getType(t)}getName(t){return this.config.getName(t)}get yupSchema(){return a.object().shape(this.shapeConfig)}buildProperties(){const t=Object.keys(this.properties),e=(this.config.buildProp||this.buildProp).bind(this);return t.reduce(e,{})}getRequiredPropsList(){return Array.isArray(this.required)?[...this.required]:[]}buildProp(t,e){const s=this.properties[e],r=this.getRequiredPropsList();return(this.config.setRequired||this.setRequired).bind(this)(s,e,r),(this.config.setPropEntry||this.setPropEntry).bind(this)(t,e,s),t}setRequired(t,e,s){const r=s.indexOf(e)>=0;return lt(t)||this.warn(`Bad property value: ${t} must be an object`),t.required=this.isRequired(t)||r,t}setPropEntry(t,e,s){t[e]={required:s.required,...s}}isRequired(t){return this.config.isRequired(t)}propsToShape(t={}){const e=this.objPropsToShape(t);return this.objPropsShape=e,this.addPropsShape=this.additionalPropsToShape(t,e),e}additionalPropsToShape(t,e){return e}objPropsToShape({name:t}){const e={...this.properties};return Object.keys(e).reduce((s,r)=>{const i=this.propToYupSchemaEntry({name:t,key:r,value:e[r]});return this.logInfo("propsToShape",{key:r,yupSchemaEntry:i}),s[r]=i,s},{})}propToYupSchemaEntry({name:t,key:e,value:s={}}){return this.createYupSchemaEntry({schema:this.schema,name:t,key:e,value:s,config:this.config,builder:this})}createYupSchemaEntry(t={}){return this.config.createYupSchemaEntry(t)}onConstraintAdded(t){this.logInfo("Constraint Added",t)}}const ut={alphanumeric:{optsKey:"locale"},alpha:{optsKey:"locale"},ascii:{},byte:{},creditCard:{},currency:{opts:"currencyOpts"},dataUri:{},dateTime:{},date:{},domainName:{opts:"domainOpts"},hash:{opts:"hashAlgo"},hexColor:{},ipv4:{},ipv6:{},isbn:{},magnetUri:{},mimeType:{},mobilePhone:{},mongoId:{},postalCode:{},uuid:{}},dt={createValidatorName:(t,e)=>`is${t=(t=(t=l.default(t||e)).replace(/Uri$/,"URI")).replace(/Id$/,"ID")}`,createTestName:(t,e)=>h.default(t||e)},pt={isMagnetURI:(t,e)=>/magnet:\?xt=urn:[a-z0-9]+:[a-z0-9]{32}/i.test(t)};exports.ConstraintBuilder=E,exports.ErrorMessageHandler=T,exports.PropertyValueResolver=it,exports.YupBuilder=ct,exports.YupSchemaEntry=at,exports.YupSchemaEntryError=nt,exports.buildYup=ht,exports.createPropertyValueResolver=rt,exports.createYupSchemaEntry=ot,exports.extendYupApi=function({constraints:e,override:s=!1,validator:r,createValidatorName:i,createTestName:n}={}){if(!r)throw"extendYupApi: missing validator option";Array.isArray(e)&&(e=((t,e={})=>t.reduce((t,s)=>{if("string"!=typeof s&&!(s instanceof Object)){if(!1!==e.throws)throw`toConstraintsMap: invalid entry ${s}`;return t}if("string"==typeof s)t[name]={};else{if(!s.name){if(!1!==e.throws)throw`toConstraintsMap: invalid entry ${s} missing name`;return t}t[s.name]=s}return t},{}))(e)),e=s?e||ut:{...ut,...e||{}},i=i||dt.createValidatorName,n=n||dt.createTestName,Object.keys(e).map(s=>{let{testName:a,optsKey:o,validatorName:h,logging:l}=e[s];const c=i(h,s);a=n(a,s),t.addMethod(t.string,s,(e={})=>{const{message:i}=e,n=e[o];return t.string().test(a,i,t=>{const{path:e,createError:o}=this;let h=r[c];if(h=h||pt[c],"function"!=typeof h)throw Error("No method named ${validatorName} on validator");const u=h(t,n);return!0===l&&console.log("Yup validator bridge",{key:s,fullValidatorName:c,testName:a,value:t,valid:u}),u||o({path:e,message:i})})})})},exports.types=X; | ||
var t=require("yup"),e=require("uniq"),s=require("dashify"),r=require("uppercamelcase");function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}function n(t){if(t&&t.__esModule)return t;var e=Object.create(null);return t&&Object.keys(t).forEach(function(s){if("default"!==s){var r=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,r.get?r:{enumerable:!0,get:function(){return t[s]}})}}),e.default=t,e}var a=/*#__PURE__*/n(t),o=/*#__PURE__*/i(e),h=/*#__PURE__*/i(s),l=/*#__PURE__*/i(r);const c={getProps:t=>t&&t.properties,getType:t=>t&&t.type,getName:t=>t&&(t.name||t.title),getConstraints:t=>t,isString:t=>t&&"string"===t.type,isArray:t=>t&&"array"===t.type,isInteger:t=>t&&("integer"===t.type||"int"===t.type),isBoolean:t=>t&&"boolean"===t.type,hasDateFormat:t=>t&&["date","date-time"].find(e=>e===t.format),isDate:t=>t&&"string"===t.type&&c.hasDateFormat(t.format),isNumber:t=>t&&("number"===t.type||c.isInteger(t)),isObject:t=>t&&"object"===t.type,isRequired:t=>t&&t.required},u={getProps:t=>t.properties,getType:t=>t.type,getName:t=>t.name||t.title,getConstraints:t=>t,isString:t=>"string"===t.type&&!u.hasDateFormat(t),isArray:t=>"array"===t.type,isBoolean:t=>"boolean"===t.type,isInteger:t=>"integer"===t.type,hasDateFormat:t=>t&&["date","date-time"].find(e=>e===t.format),isDate:t=>"string"===t.type&&u.hasDateFormat(t),isNumber:t=>"number"===t.type||u.isInteger(t),isObject:t=>"object"===t.type,isRequired:t=>t.required},d={getProps:t=>t&&t.fields,getType:t=>t&&t.type,getName:t=>t&&(t.name||t.title),getConstraints:t=>t,isString:t=>t&&"string"===t.type,isArray:t=>t&&"array"===t.type,isInteger:t=>t&&"int"===t.type,isFloat:t=>t&&"float"===t.type,isDouble:t=>t&&"double"===t.type,isBoolean:t=>t&&"boolean"===t.type,isDate:t=>t&&"int"===t.type&&"date"===t.logicalType,isNumber:t=>t&&(d.isInteger(t)||d.isFloat(t)||d.isDouble(t)),isObject:t=>t&&"record"===t.type,isRequired:t=>t&&t.required},p={"json-schema":c,"type-def":u,avro:d};class g extends class{constructor(t={}){this.config=t;const{log:e,error:s}=t,r=t.enable||{};!0===t.logging&&(r.log=!0),!1===t.logging&&(r.log=!1),this.enable=r,this.log="function"==typeof e?e:console.log,this.err="function"==typeof s?s:console.error}error(t){var e=[].slice.call(arguments,1);if(!1!==this.enable.error&&this.err)throw e&&e.length?this.err(t,...e):this.err(t),t}warn(t){this.enable.warn&&this.logInfo("WARNING: "+t,...[].slice.call(arguments,1))}logTypeInfo(t){if(!this.enable.log)return;if(!this.log)return;const e=this.config.logTypes||[];e.length&&e.find(t=>this.type===t)&&logInfo(t,...[].slice.call(arguments,1))}logDetails(t,e){const s=this.config.logDetailed||[];s.length&&s.find(t=>!(t.key&&e.key!==t.key||t.constraintName&&e.constraintName!==t.constraintName||t.propName&&e.propName!==t.propName||t.method&&e.method!==t.method))&&this.logInfo(t,e,...[].slice.call(arguments,2))}logInfo(t){var e=[].slice.call(arguments,1);this.enable.log&&this.log&&(e&&e.length?this.log(t,...e):this.log(t))}}{constructor(t={}){super(t)}isNothing(t){return null==t}isPresent(t){return!this.isNothing(t)}hasKey(t,e){if(this.isObjectType(t))return Object.keys(t).includes(e)}toNumber(t){return Number(t)}isNumberLike(t){return!isNaN(this.toNumber(t))}isObjectType(t){return t===Object(t)}isArrayType(t){return Array.isArray(t)}isNumberType(t){return!isNaN(t)}isStringType(t){return"string"==typeof t}isFunctionType(t){return"function"==typeof t}isDateType(t){return t instanceof Date}}class y{constructor(t,e){this.schemaParserMap=t,this.name=e}lookup(t=this.name){return this.schemaParserMap[t]}build(){const t=this.lookup();if(t.extends){const e=this.extend(t.extends);if(e)return e}return t}extend(t){const e=this.lookup(t);e&&(entry={...e,...this.lookup()})}}class m extends g{constructor(t={}){super(t);const e=(t.createSchemaParserBuilder||new y(t.schemaParserMap||p,t.schemaType||"json-schema")).build();this.config={...e,...t}}createSchemaParserBuilder(t,e){return new SchemaParserBuilder(t,e)}}function f(t){return t===Object(t)}class b{constructor(t,e={}){this.whenEntryObj=t;const{schema:s,properties:r,config:i,key:n,when:a,type:o}=e;this.schema=s,this.when=a,this.properties=r||{},this.key=n,this.type=o,this.config=i}validateAndConfigure(t){if(!f(t=t||this.whenEntryObj))return this.warn("invalid or missing when entry constraint object",t),!1;const e=Object.keys(t);return e.length<2?(this.warn(`validateAndConfigure: when entry constraint must have at least 2 keys: ${e}`,t),!1):this.hasKey(e,"is")?!!this.hasKey(e,"then")||(this.warn(`validateAndConfigure: when entry constraint missing 'then' or 'else' constraint: ${e}`,t),!1):(this.warn(`validateAndConfigure: when entry constraint missing 'is' constraint: ${e}`,t),!1)}createYupSchemaEntry(t){return this.config.createYupSchemaEntry(t)}createValue(t,e){return"string"==typeof t&&(t={[t]:!0}),f(t)||this.error(`createValue: ${e} must be a schema object`),{key:this.key,type:this.type,...t}}createEntryOpts(t,e){const s=this.createValue(t,e);return{schema:this.schema,properties:this.properties,key:this.key,type:this.type,value:s,config:this.config}}createEntry(t,e){const s=this.createEntryOpts(t,e);return this.createYupSchemaEntry(s)}hasKey(t,e){return t.find(t=>t===e)}hasAnyKey(t,e){return t.find(t=>e.includes(t))}whenEntryFor(t,e,s){if(s=s||e,"string"==typeof t&&(t={[t]:!0}),!f(t))throw`whenEntryFor: Invalid when object ${t}`;const r={...t[s]};return delete t[s],r?(t[e]=this.createEntry(r,e),t):t}calcEntryObj(){let t={...this.whenEntryObj};return t=this.whenEntryFor(t,"then"),"otherwise"in t&&(t=this.whenEntryFor(t,"otherwise")),"else"in t&&(t=this.whenEntryFor(t,"else")),t}get entryObj(){return this.validateAndConfigure()&&this.calcEntryObj()}warn(t,e){console.error("[WhenEntry] WARNING",t,e)}error(t,e){throw console.error("[WhenEntry] ERROR",t,e),t}}function v(t){return t===Object(t)}class C{constructor(t={}){const{type:e,key:s,value:r,when:i,schema:n,properties:a,config:o}=t;this.opts=t,this.when=i,this.key=s,this.type=e,this.value=r,this.schema=n,this.properties=a,this.config=o,this.validate()}validate(){"string"!=typeof this.type&&this.error(`validate: invalid or mising type: ${this.type}`,this.opts),v(this.when)||this.error(`validate: invalid or mising when: ${this.when}`,this.opts)}validateAndConfigure(t){if(!v(t=t||this.when))return this.warn("invalid or missing when constraint",t),!1;const e=Object.keys(t);return e.length<1?(this.warn(`when constraint must have at least 1 key: ${e}`,t),!1):(this.whenKeys=e,!0)}createWhenEntry(t,e){return((t,e={})=>new b(t,e))(t,e)}accumulate(t,e){let s=this.when[e];if(!v(s))return this.warn(`invalid when entry constraint object ${s} for ${e}`),t;const r={type:this.type,key:this.key,schema:this.schema,properties:this.properties,config:this.config},{entryObj:i}=this.createWhenEntry(s,r);return i?t=Object.assign(t,i):t}get constraintObj(){return this.whenKeys?this.whenKeys.reduce(this.accumulate.bind(this),{}):{}}get keyVal(){const t=this.whenKeys||[];return 1===t.length?t[0]:t}get constraintValue(){return!!this.keyVal&&[this.keyVal,this.constraintObj]}get constraint(){return this.validateAndConfigure()&&this.constraintValue}warn(t,e){console.error("[WhenCondition] WARNING",t,e)}error(t,e){throw console.error("[WhenCondition] ERROR",t,e),t}}const N=t=>new C(t);class w extends g{constructor(t,e={}){super(e),this.typeHandler=t,this.type=t.type,this.builder=t.builder,this.constraintsAdded={},this.delegators.map(e=>{this[e]=t[e]})}get delegators(){return["errMessages","base","key","type","constraints","errorMessageHandler","logInfo","warn"]}build(t,e={}){let{constraintName:s,constraintValue:r,propValue:i,method:n,yup:a,value:o,values:h,errName:l}=e;if(a=a||this.base,r=this.getFirstValue([r,i,this.constraints[t]]),s=s||t,n=n||s,this.idObj={propName:t,method:n,constraintName:s,key:this.key},this.logDetailed("build",e,{resolved:{constraintValue:r,constraintName:s}}),this.isNothing(r))return this.warn("no prop value",{constraintValue:r}),!1;const c=this.aliasMap[n]||n;if(!a[c])return this.warn(`Yup has no such API method: ${c}`),!1;const u=a[c].bind(a),d=this.validationErrorMessage(s),p=l&&this.validationErrorMessage(l),g={constraintName:s,yup:a,constraintFn:u,errFn:d||p},y=["multiValueConstraint","presentConstraintValue","nonPresentConstraintValue"];let m;const f=this.type;for(let t of y)if(m=this[t].bind(this)(this.getFirstValue([o,h,r],{constraintName:s,type:f}),g),m)break;return m?(this.base=m,m):(this.warn("buildConstraint: missing value or values options"),!1)}yupRefMap(){return{string:["length","min","max"],number:["min","max","lessThan","moreThan"],date:["min","max"],array:["length","min","max"]}}getFirstValue(t,e={}){const{constraintName:s,type:r}=e,i=this.isPresent.bind(this),n=this.yupRefMap[r],o=t.filter(i)[0];return n&&n.includes(s)&&this.isStringType(o)?a.ref(o):o}nonPresentConstraintValue(t,{constraintName:e,constraintFn:s,errFn:r}){if(!this.isPresent(t))return this.logInfo("nonPresentConstraintValue",{constraintValue:t}),this.onConstraintAdded({method:"nonPresentConstraintValue",name:e}),s(r)}presentConstraintValue(t,{constraintName:e,constraintFn:s,errFn:r}){if(this.isPresent(t))return this.logInfo("presentConstraintValue",{constraintName:e,constraintValue:t}),this.onConstraintAdded({method:"presentConstraintValue",name:e,value:t}),this.isNoValueConstraint(e)?(this.logInfo("isNoValueConstraint",{constraintName:e}),s(r)):(this.logInfo("presentConstraintValue: apply validator function",{constraintName:e,constraintValue:t}),s(t,r));this.logInfo("presentConstraintValue: value not present",{constraintName:e,constraintValue:t})}multiValueConstraint(t,{constraintFn:e,constraintName:s,errFn:r}){if(this.isPresent(t)){if(this.logInfo("multiValueConstraint",{constraintName:s,values:t}),Array.isArray(t))return this.onConstraintAdded({method:"multiValueConstraint",name:s,value:t}),this.logInfo("multiValueConstraint: apply validator function",{constraintName:s,value:t}),this.callConstraintFn(e,s,t,r);this.warn("buildConstraint: values option must be an array of arguments")}}callConstraintFn(t,e,s,r){return this.isMultiArgsCall(e)?t(...s,r):t(s,r)}isMultiArgsCall(t){return this.multiArgsValidatorMethods[t]}get multiArgsValidatorMethods(){return this.config.multiArgsValidatorMethods||{when:!0}}isNoValueConstraint(t){return this.noValueConstraints.includes(t)}get noValueConstraints(){return["required","email","url","format"]}addTrueValueConstraint(t,{constraintName:e,errName:s}={}){return this.addConstraint(t,{constraintName:e,value:!0,errName:s})}addConstraint(t,e){const s=this.build(t,e);return!!s&&(this.typeHandler.base=s,s)}onConstraintAdded({method:t,name:e,value:s}){if(this.constraintsAdded[e]=s,this.builder)return this.builder.onConstraintAdded({type:this.type,method:t,name:e,value:s}),this.typeHandler;this.logInfo("no builder set to notify in ConstraintBuilder")}get constraintsMap(){return{simple:["required","notRequired","nullable"],value:["default","strict"]}}logDetailed(t){this.logDetails(t,this.idObj,...[].slice.call(arguments,1))}validationErrorMessage(t){return this.errorMessageHandler.validationErrorMessage(t)}get aliasMap(){return{oneOf:"oneOf",enum:"oneOf",anyOf:"oneOf"}}}class E extends g{constructor(t,e={}){super(e),this.typeHandler=t,this.init()}init(){const{typeHandler:t}=this;this.constraints=t.constraints,this.errMessages=t.errMessages,this.key=t.key,this.value=t.value,this.constraints=t.constraints,this.parentNode=t.parentNode,this.type=t.type,this.description=t.description,this.title=t.title,this.setErrMessage()}errMessageMap(t={}){return t[this.errMessagesMapKey]||this.errMessages}get errMessageKey(){return this.config.errMessageKey||"errMessage"}get errMessagesMapKey(){return this.config.errMessagesMapKey||"errMessages"}setErrMessage(){const{typeHandler:t}=this,{value:e}=t;if(!e.errMessage)return;const s=this.errMessageKey,r=this.errMessageMap(e);return r[this.key]=e[s]||r[this.key],this}validationErrorMessage(t){const{constraints:e,key:s,description:r,title:i,typeHandler:n,parentNode:a}=this,o=this.errMessageFor(t);return"function"==typeof o?o(e,{key:s,title:i,description:r,typeHandler:n,parentNode:a}):o}errMessageFor(t){const{errMessages:e,key:s}=this,r=e[s];return r?r[t]:e[`$${t}`]}}class T extends Error{}class O extends m{constructor(t={}){super(t.config),this.init(t)}init(t){let{schema:e,key:s,value:r,config:i,entryHandler:n,parentNode:a}=t;i=i||{},e=e||{},this.parentNode=a||n.parentNode,this.validateOnCreate(s,r,t),this.opts=t,this.entryHandler=n,this.validator=this.getValidator(),this.key=s,this.schema=e,this.properties=e.properties||{},this.value=r,this.title=r.title,this.description=r.description,this.constraints=this.getConstraints(),this.format=r.format||this.constraints.format,this.config=i||{},this.type=this.baseType,this.mixedConfig=this.config.mixedEnabled||{},this.typeConfig=this.config[this.type]||{},this.errMessages=i.errMessages||{},this.configureTypeConfig(),this.constraintsAdded={},this.base=this.getBase()}get builder(){return this.entryHandler&&this.entryHandler.builder}getBase(){return this.customBaseValidator||this.validatorInstance}get customBaseValidator(){return this.config.validatorFor&&this.config.validatorFor(this.type)}getValidator(){return this.opts.validator||this.config.validator||this.builder&&this.builder.validator||a}get baseType(){return"mixed"}get validatorInstance(){return this.validator.mixed()}configureTypeConfig(){this.typeConfig.enabled||this.typeConfig.extends||this.typeConfig.convert&&(this.typeConfig.extends=Object.keys(this.typeConfig.convert))}isRequired(t){return!0===(t=t||this.value).required}get mode(){return this.config.mode||{}}get disableFlags(){return[!1,"disabled","no","off"]}get enableFlags(){return[!0,"enabled","yes","on"]}disabledMode(t){const e=this.mode[t];return!!this.disableFlags.find(t=>e===t)}enabledMode(t){const e=this.mode[t];return!!this.enableFlags.find(t=>e===t)}get shouldPreProcessValue(){return!this.disabledMode("notRequired")}preProcessedConstraintValue(t){return this.shouldPreProcessValue?this.isRequired(t)?t:{...t,notRequired:!0}:t}set value(t){this._value=this.preProcessedConstraintValue(t)}get value(){return this._value}initHelpers(){const{config:t}=this;this.errorMessageHandler=(this.config.createErrorMessageHandler||this.createErrorMessageHandler)(this,t),this.constraintBuilder=(this.config.createConstraintBuilder||this.createConstraintBuilder)(this,t),this.rebind("addConstraint","addTrueValueConstraint")}createConstraintBuilder(t,e={}){return new w(t,e)}createErrorMessageHandler(t,e={}){return new E(t,e)}rebind(){[].slice.call(arguments).map(t=>{const e=this[t];this[t]=this.isFunctionType(e)?e.bind(this):e})}validateOnCreate(t,e,s){t||this.error(`create: missing key ${JSON.stringify(s)}`),e||this.error(`create: missing value ${JSON.stringify(s)}`)}get mixedEnabled(){return this.mixedConfig.enabled||["oneOf","notOneOf","when","nullable","isType","label","const","refValueFor"]}get typeEnabled(){return[]}get $typeExtends(){if(Array.isArray(this.typeConfig.extends))return o.default([...this.typeConfig.extends,...this.typeEnabled])}get configuredTypeEnabled(){return Array.isArray(this.typeConfig.enabled)?this.typeConfig.enabled:this.typeEnabled}get $typeEnabled(){return this.$typeExtends||this.configuredTypeEnabled}get enabled(){return[...this.mixedEnabled,...this.$typeEnabled]}convertEnabled(){this.enabled.map(t=>{const e=this.convertFnFor(t);e&&e(this)})}convertFnFor(t){return this.customConvertFnFor(t,this)||this.builtInConvertFnFor(t)}customConvertFnFor(t){return(this.typeConfig.convert||{})[t]}builtInConvertFnFor(t){return this[t].bind(this)}getConstraints(){return this.config.getConstraints(this.value)}createSchemaEntry(){return this.convert().base}convert(){return this.initHelpers(),this.addMappedConstraints(),this.convertEnabled(),this}apply(t){var e=[].slice.call(arguments,1);if("string"!=typeof t)throw new TypeError("[Mixed] apply must take a method name available on the validator instance as first argument");return this.base=e&&e.length&&this.base[t](...e)||this.base,this}applyArr(t,e){if("string"!=typeof t)throw new TypeError("[Mixed] apply must take a method name available on the validator instance as first argument");return this.base=e&&e.length&&this.base[t](e)||this.base,this}addTrueValueConstraint(t,e){const s=this.constraintBuilder.addTrueValueConstraint(t,e);if(s){const{base:t}=s;this.base=t}return this}addConstraint(t,e){if(!this.constraintBuilder)throw new Error(`[YupMixed] addConstraint: Missing constraintBuilder in ${this.constructor.name}`);const s=this.constraintBuilder.addConstraint(t,e);return s&&(this.base=s),this}addMappedConstraints(){const t=Object.keys(this.constraintsMap),e=this.addMappedConstraint.bind(this);return t.map(e),this}addMappedConstraint(t){const{constraintsMap:e}=this,s=this["trueValue"===t?"addTrueValueConstraint":"addConstraint"],r=this.constraints[t];e[t].map(t=>{s(t,{value:r})})}get constraintsMap(){return{simple:["default","required","notRequired","nullable"],trueValue:["strict"]}}refValueFor(){let t=this.constraints.refValueFor;return this.isNothing(t)?this:(this.logInfo("refValueFor",{propRefName:t}),this.apply("when",(e,s)=>e?s.required().oneOf([a.ref(t)]):s))}normalizeValues(t){return Array.isArray(t)?t:[t]}get oneOfValues(){return this.constraints.enum||this.constraints.oneOf||this.constraints.anyOf}get oneOfAliases(){return["oneOf","enum","anyOf"]}get oneOfAlias(){return this.oneOfAliases.find(t=>void 0!==this.constraints[t])}oneOf(){let t=this.oneOfValues;if(this.isNothing(t))return this;t=this.normalizeValues(t);const e=this.resolveValues(t),s=this.oneOfAlias;return this.logDetails("type",{constraintName:s,method:"oneOf",key:this.key,type:this.type},t,e),this.addConstraint(s,{values:e})}logDetailed(t,e){this.logDetails(t,e,...[].slice.call(arguments,2))}get notOneOfValues(){const{not:t,notOneOf:e}=this.constraints;return e||t&&(t.enum||t.oneOf)}notOneOf(){let t=this.oneOfValues;if(this.isNothing(t))return this;t=this.normalizeValues(t);const e=this.resolveValues(t);return this.logDetails("type",{constraintName:"notOneOf",method:"notOneOf",key:this.key,type:this.type},t,e),this.addConstraint("notOneOf",{values:e})}resolveValues(t){return t.map(t=>this.isObjectType(t)?this.resolveValue(t):t)}const(){let t=this.constraints.const;if(this.isNothing(t))return this;if(this.isDataRef(t)){const e=this.normalizeDataRefPath(t);t=a.ref(e)}return this.addConstraint("const",{value:t})}normalizeDataRefPath(t){return(t=t.$data||t).split("/").shift().join("/")}isDataRef(t){return this.isPresent(t.$data)}isConst(t){return this.hasKey(t,"const")}resolveValue(t){return this.isConst(t)?t.const:(0,this.config.createYupSchemaEntry)({schema:this.schema,key:this.key,value:t,config:this.config})}validationErrorMessage(t){const e=this.errorMessageHandler.validationErrorMessage.bind(this.errorMessageHandler);return(this.config.validationErrorMessage||e)(t,this)}createWhenConditionFor(t){return(this.config.createWhenCondition||N)({key:this.key,type:this.type,value:this.value,schema:this.schema,properties:this.properties,config:this.config,when:t})}label(){const t=this.value,e=t.title||t.label;return this.base=e&&this.base.label(e)||this.base,this}when(){const t=this.constraints.when;if((e=t)!==Object(e))return this;var e;const{constraint:s}=this.createWhenConditionFor(t);return s?(this.logInfo(`Adding when constraint for ${this.key}`,s),this.addConstraint("when",{values:s,errName:"when"}),this):(this.warn(`Invalid when constraint for: ${t}`),this)}isType(){return this.addConstraint("isType",{value:this.constraints.isType,errName:"notOneOf"}),this}nullable(){const{nullable:t,isNullable:e}=this.constraints;return this.addConstraint("nullable",{value:t||e,errName:"notOneOf"}),this}message(){return config.messages[this.key]||config.messages[this.type]||{}}errMessage(t="default"){return this.message[t]||"error"}toValidJSONSchema(){}normalize(){}deNormalize(){}errorMsg(t){this.throwError(t)}error(t,e){const s=[`[${t}]`,e].join(" ");this.errorMsg(s)}throwError(t){throw t}}const x=["oneOf","enum","required","notRequired","minDate","min","maxDate","max","trim","lowercase","uppercase","email","url","minLength","maxLength","pattern","matches","regex","integer","positive","minimum","maximum"],M={errMessages:(t=x)=>t.reduce((t,e)=>(t[e]=({key:t,value:e})=>`${t}: invalid for ${e.name||e.title}`,t),{})};class V extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance,this.createYupSchemaEntry=this.config.createYupSchemaEntry}get baseType(){return"array"}get validatorInstance(){return this.validator.array()}static create(t){return new V(t)}convert(){return super.convert(),this}get typeEnabled(){return["maxItems","minItems","ensureItems","compact","itemsOf"]}ensureItems(){return this.addConstraint("ensure")}compact(){return this.addConstraint("compact")}itemsOf(){const{items:t,itemsOf:e}=this.constraints,s=t||e||this.constraints.of;if(!this.isNothing(s))if(Array.isArray(s))this.error("itemsOf","does not (yet) support an Array of schemas");else if(this.isObjectType(s)){if(this.createYupSchemaEntry){try{const t=s,e={key:this.key,value:t,config:this.config};this.logTypeInfo("array:of",{schemaConf:e});const r=this.createYupSchemaEntry(e);return this.logTypeInfo("array:of",{schemaEntry:r}),this.addConstraint("of",{constraintValue:r,propValue:t,value:r})}catch(t){this.error("itemsOf: Error",t)}return this}this.warn("missing createYupSchemaEntry in config, needed for recursive validation")}else this.error("itemsOf","must be a schema object, was "+typeof s)}maxItems(){const{maxItems:t,max:e}=this.constraints,s=t||e;if(!this.isNumberType(s))return this;if(!this.isValidSize(s))return this.handleInvalidSize("maxItems",s);const r=s&&this.base.max(s);return this.base=r||this.base,this}minItems(){const{minItems:t,min:e}=this.constraints,s=t||e;if(!this.isNumberType(s))return this;if(!this.isValidSize(s))return this.handleInvalidSize("minItems",s);const r=s&&this.base.min(s);return this.base=r||this.base,this}$items(){return this}$additionalItems(){return this}$uniqueItems(){return this}$contains(){return this}handleInvalidSize(t,e){const s=`invalid array size constraint for ${t}, was ${e}. Must be a number >= 0`;return this.config.warnOnInvalid?(this.warn(s),this):(this.error(s,e),this)}isValidSize(t){return this.isNumberType(t)&&t>=0}}class k extends m{constructor(t){super(t)}isArray(t){return this.config.isArray||this.error("ArrayHandler: missing isArray in config",this.config),this.config.isArray(t)}handle(t){return this.isArray(t)&&V.create(t).createSchemaEntry()}}function S(t,e={}){return t&&new k(e).handle(t)}class I extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance}get baseType(){return"boolean"}get validatorInstance(){return this.validator.boolean()}static create(t){return new I(t)}}class j{constructor(t){this.config=t}isBoolean(t){return this.config.isBoolean(t)}handle(t){return this.isBoolean(t)&&I.create(t).createSchemaEntry()}}function A(t,e={}){return t&&new j(e).handle(t)}class D extends g{constructor(t,e){super(t.config),this.map=e||this.$map||{},this.typeHandler=t,this.delegates.map(e=>{const s=t[e];s||this.error(`missing delegate: ${e}`,{typeHandler:t}),this[e]=this.isFunctionType(s)?s.bind(t):s})}isStringType(t){return"string"==typeof t}get delegates(){return["constraints","addConstraint","constraintsAdded"]}add(){const t=this.map;Object.keys(t).map(e=>{const s=this.entryNames(t[e]);this.addConstraints(e,s)})}entryNames(t){return Array.isArray(t)?t:[t]}addConstraints(t,e=[]){return e.map(e=>{const s=this.validateAndTransform(e);this.addConstraint(e,{method:t,value:s})}),this}validateAndTransform(t){const e=this.constraints[t];return this.validate(t,e),this.transform(e)}invalidMsg(t,e){return`invalid constraint for ${t}, was ${e}.`}get explainConstraintValidMsg(){return""}invalidConstraintMsg(t,e){return[this.invalidMsg(t,e),this.explainConstraintValidMsg].join("\n")}validate(t,e){return this.isNothing(e)?this:this.isValidConstraint(e)?void 0:this.handleInvalidConstraint(t,e)}isValidConstraint(t){return!0}handleInvalidConstraint(t,e){const s=this.invalidConstraintMsg(t,e);return this.config.warnOnInvalid?(this.warn(s),this):(this.error(s,e),this)}}class P extends D{constructor(t){super(t)}transform(t){return this.typeHandler.toNumber(t)}isValidConstraint(t){return this.typeHandler.isNumberLike(t)||this.typeHandler.isStringType(t)}get explainConstraintValidMsg(){return"Must be a number or convertible to a number"}}class F extends P{constructor(t){super(t)}get $map(){return{moreThan:["exclusiveMinimum","moreThan"],lessThan:["exclusiveMaximum","lessThan"],max:["maximum","max"],min:["minimum","min"]}}}class R extends m{constructor(t,e){super(e),this.obj=t}isValid(){return!1}verify(){return this.isPresent(this.obj)&&this.isValid(this.obj)}}class H extends R{constructor(t,e){super(t,e)}isValid(){return this.config.isNumber(this.obj)}}const $=(t,e={})=>function(t,e){return new H(t,e)}(t,e).verify();function Y(t,e={}){return $(t,e)&&function(t){return q.schemaEntryFor(t)}(t)}class q extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance,this.rangeConstraint=new F(this)}get baseType(){return this.normalizeNumType(this.opts.type)}get validatorInstance(){return this.validator.number()}normalizeNumType(t){return"int"===t?"integer":t}static create(t){return new q(t)}static schemaEntryFor(t){return q.create(t).createSchemaEntry()}get typeEnabled(){return["range","posNeg","integer"]}convert(){return super.convert(),this}range(){this.rangeConstraint.add()}truncate(){return this.addConstraint("truncate")}round(){const{round:t}=this.constraints;if(this.isNothing(t))return this;const e=this.isStringType(t)?t:"round";return t&&this.base.round(e),this}posNeg(){this.positive(),this.negative()}integer(){return this.isInteger&&this.addConstraint("integer"),this}get isInteger(){return this.config.isInteger(this.type)}positive(){return this.addConstraint("positive")}negative(){return this.addConstraint("negative")}get isNegative(){const{exclusiveMaximum:t,negative:e}=this.constraints;return!!e||void 0!==t&&0===t}get isPositive(){const{exclusiveMinimum:t,positive:e}=this.constraints;return!!e||void 0!==t&&0===t}normalize(){this.constraints.maximum=this.constraints.maximum||this.constraints.max,this.constraints.minimum=this.constraints.minimum||this.constraints.min}}class B extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance,this.properties=this.value.properties}get baseType(){return"object"}get validatorInstance(){return this.validator.object()}static create(t){return new B(t)}get typeEnabled(){return["noUnknown","camelCase","constantCase"]}convert(){if(!this.properties)return this;super.convert();const t=this.value,e=this.config;if(t){e.buildYup||this.error("convert","Missing buildYup function from config",e);const s={key:this.key,...this.value},r=this.config.buildYup(t,e,s);this.base=r}return this}camelCase(){return this.addConstraint("camelCase")}constantCase(){return this.addConstraint("constantCase")}noUnknown(){const{noUnknown:t,propertyNames:e}=this.value,s=t||e,r=s&&this.base.noUnknown(s,this.validationErrorMessage("propertyNames")||this.validationErrorMessage("noUnknown"));return this.base=r||this.base,this}}const z=t=>t&&"object"===t.type;class K{constructor(t={}){(t=t||{}).isObject=t.isObject||z,this.config=t,this.schema=t.schema}isObject(t){return this.config.isObject(t.value)}handle(t){return this.isObject(t)&&B.create({...t,config:this.config}).createSchemaEntry()}}function L(t,e={}){return t&&function(t={}){return new K(t)}(e).handle(t)}class U extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance}get baseType(){return"string"}get validatorInstance(){return this.validator.string()}static create(t){return new U(t)}convert(){return super.convert(),this}get typeEnabled(){return["normalize","minLength","maxLength","pattern","lowercase","uppercase","email","url","genericFormat"]}trim(){return this.addConstraint("trim")}lowercase(){return this.addConstraint("lowercase")}uppercase(){return this.addConstraint("uppercase")}genericFormat(){1!=!this.config.format&&this.validator.prototype[this.format]&&this.addConstraint(this.format)}email(){if(!this.isEmail)return this;const t=this.constraintNameFor("email","format"),e="email";return this.addConstraint("email",{constraintValue:!0,constraintName:t,method:e,errName:e}),this}constraintNameFor(){return[].slice.call(arguments).find(t=>this.constraints[t])}get isEmail(){return this.constraints.email||"email"===this.format}url(){if(!this.isUrl)return this;const t=this.constraintNameFor("url","format");return this.addConstraint("url",{constraintValue:!0,constraintName:t,method:"url",errName:"url"}),this}get isUrl(){return this.constraints.url||"url"===this.format}minLength(){const{minLength:t}=this.constraints,e=this.validationErrorMessage("minLength")||this.validationErrorMessage("min"),s=t&&this.base.min(t,e);return this.base=s||this.base,this}maxLength(){const{maxLength:t}=this.constraints,e=this.validationErrorMessage("maxLength")||this.validationErrorMessage("max"),s=t&&this.base.max(t,e);return this.base=s||this.base,this}pattern(){const{pattern:t,flags:e,excludeEmptyString:s}=this.constraints;if(!t)return this;const r=new RegExp(t,e),i=this.validationErrorMessage("pattern")||this.validationErrorMessage("matches")||this.validationErrorMessage("regex"),n=r&&this.base.matches(r,{message:i,excludeEmptyString:s});return this.base=n||this.base,this}normalize(){this.constraints.pattern=this.constraints.pattern||this.constraints.matches||this.constraints.regex,this.constraints.maxLength=this.constraints.maxLength||this.constraints.max,this.constraints.minLength=this.constraints.minLength||this.constraints.min}}class W{constructor(t){this.config=t}isString(t){return this.config.isString(t)}handle(t){return this.isString(t)&&U.create({config:this.config,...t}).createSchemaEntry()}}function _(t,e={}){return t&&new W(e).handle(t)}class J extends O{constructor(t){super(t),this.type=this.baseType,this.base=this.validatorInstance}get baseType(){return"date"}get validatorInstance(){return this.validator.date()}static create(t){return new J(t)}get typeEnabled(){return["minDate","maxDate"]}convert(){return super.convert(),this}toDate(t){return this.isStringType(t)&&!this.isValidDateFormat(t)?a.ref(t):new Date(t)}isValidDateType(t){return this.isStringType(t)||this.isDateType(t)}isValidDate(t){return!!this.isValidDateType(t)}isValidDateFormat(t){try{const e=Date.parse(t);return Boolean(e)}catch(t){return!1}}transformToDate(t){return this.isNumberType(t)?new Date(t):t}minDate(){const t=this.constraints.minDate||this.constraints.min;if(this.isNothing(t))return this;const e=this.transformToDate(t);if(!this.isValidDateType(e))return this.handleInvalidDate("minDate",e);const s=e&&this.base.min(this.toDate(e),this.validationErrorMessage("minDate")||this.validationErrorMessage("min"));return this.base=s||this.base,this}maxDate(){const t=this.constraints.maxDate||this.constraints.max;if(this.isNothing(t))return this;const e=this.transformToDate(t);if(!this.isValidDateType(e))return this.handleInvalidDate("maxDate",e);const s=e&&this.base.max(this.toDate(e),this.validationErrorMessage("maxDate")||this.validationErrorMessage("max"));return this.base=s||this.base,this}handleInvalidDate(t,e){const s=`invalid constraint for ${t}, was ${e}. Must be a number, string (valid date format) or a Date instance`;return this.config.warnOnInvalid?(this.warn(s),this):(this.error(s,e),this)}}class G{constructor(t){this.config=t}isDate(t){return this.config.isDate(t)}isDateCompatible(t){return this.config.isString(t)}handle(t){return J.create(t).createSchemaEntry()}}function Q(t,e={}){return t&&new G(e).handle(t)}var X={__proto__:null,errValKeys:x,defaults:M,YupArray:V,toYupArray:S,YupBoolean:I,toYupBoolean:A,YupNumber:q,toYupNumberSchemaEntry:Y,toYupNumber:function(t,e={}){return $(t,e)&&function(t){return q.create(t)}(t)},YupObject:B,toYupObject:L,YupString:U,toYupString:_,YupDate:J,toYupDate:Q,YupMixed:O,ConvertYupSchemaError:T,Base:m};class Z extends Error{}class tt extends m{constructor(t,e,s){super(e);const{value:r,type:i,kind:n,name:a,key:o,schema:h,types:l,parentNode:c}=t;this.entryHandler=s||t.entryHandler,this.parentNode=c,this.builder=t.builder,this.opts=t,this.kind=n,this.value=r,this.schema=h,this.key=o,this.value=r||{},this.name=a,this.type=i,this.types=l}get validator(){return this.builder.validator}error(t,e){let{opts:s}=this;throw s=s||{},s=e?{data:e,...s}:s,console.error(t,...s),new Z(t)}resolve(){throw"Must be implemented by subclass"}get obj(){const{schema:t,key:e,value:s,type:r,kind:i,config:n,entryHandler:a,parentNode:o}=this;return{schema:t,parentNode:o,key:e,value:s,type:r,kind:i,config:n,entryHandler:a}}}class et extends tt{constructor(t,e,s){super(t,e,s)}resolve(){const{value:t}=this;if(!Array.isArray(t))return;const e=this.config.toMultiType;return e?e(this):this.oneOf()}oneOf(){const t=this.value,e=this.createEntry.bind(this),s=t.map(e);return this.mixed().oneOf(s)}notOneOf(){const t=this.value,e=this.createEntry.bind(this),s=t.map(e);return this.mixed().notOneOf(s)}createEntry(t){const{createYupSchemaEntry:e}=this.config;return t=normalizedValue(t),e({schema:this.schema,key:this.key,value:t,config:this.config})}normalizedValue(t){return"string"==typeof t?{type:t}:t}mixed(){return this.validator.mixed()}}class st extends tt{constructor(t,e,s){super(t,e,s)}resolve(){const{value:t}=this;if(Array.isArray(t))return;const e=this.config.toSingleType;if(e)return e(this);const{obj:s,config:r,entryHandler:i}=this,n=Object.keys(this.types);let a;for(let t of n){const e=this.types[t];if(e&&(a=e(s,r,i)),a)break}return a}}const rt=(t,e,s)=>new it(t,e,s);class it extends tt{constructor(t,e,s){super(t,e,s),this.initResolvers()}initResolvers(){const{opts:t,config:e,entryHandler:s}=this,r=e.createMultiTypeResolver||this.createMultiTypeResolver.bind(this);this.multiTypeResolver=r(t,e,s);const i=e.createSingleTypeResolver||this.createSingleTypeResolver.bind(this);this.singleTypeResolver=i(t,e,s)}createMultiTypeResolver(){const{opts:t,config:e,entryHandler:s}=this;return new et(t,e,s)}createSingleTypeResolver(){const{opts:t,config:e,entryHandler:s}=this;return new st(t,e,s)}resolve(){return this.toMultiType()||this.toSingleType()||this.toDefaultEntry()}toMultiType(){return(this.config.toMultiType||this.singleTypeResolver.resolve.bind(this.singleTypeResolver))(this)}toSingleType(){return(this.config.toSingleType||this.singleTypeResolver.resolve.bind(this.singleTypeResolver))(this)}toDefaultEntry(){return this.defaultType()}defaultType(){return this.error("toEntry: unknown type",this.type),!1}}class nt extends Error{}class at extends m{constructor(t){super(t.config);const{schema:e,name:s,key:r,value:i,config:n,builder:a,parentNode:o}=t;this.parentNode=o,this.builder=a,this.opts=t,this.schema=e,this.key=r,this.value=i||{},this.config=n||{},this.name=s,this.init()}get calcType(){const{value:t}=this;return Array.isArray(t)?"array":t.type}get calcKind(){return"array"===this.type?"multi":"single"}createNew(t){return new at(t).toEntry()}init(){this.type=this.calcType,this.kind=this.calcKind,this.setTypeHandlers(),this.setPropertyHandler()}get validator(){return this.builder&&this.builder.validator}setPropertyHandler(){const{config:t}=this;this.propertyValueHandler=(t.createPropertyValueHandler||this.createPropertyValueHandler)(this.propertyHandlerOpts,t)}get propertyHandlerOpts(){const{types:t,value:e,name:s,key:r,type:i,kind:n,schema:a,parentNode:o}=this;return{type:i,parentNode:o,kind:n,types:t,value:e,name:s,key:r,schema:a,entryHandler:this}}createPropertyValueHandler(t,e){return rt(t,e,this)}get defaultTypeHandlerMap(){return{string:_,number:Y,boolean:A,array:S,object:L,date:Q}}setTypeHandlers(){this.types=this.config.types||this.typeHandlers}get typeHandlers(){return{...this.defaultTypeHandlerMap,...this.config.typeHandlers||{}}}isValidSchema(){const{type:t}=this;return this.isStringType(t)}error(t,e){const{opts:s}=this;throw e?console.error(t,e,...s):console.error(t,...s),new nt(t)}toEntry(){if(!this.isValidSchema()){const t=JSON.stringify(this.schema);this.error(`Not a valid schema: type ${this.type} must be a string, was ${typeof this.type} ${t}`)}const{opts:t,config:e}=this;return this.propertyValueHandler.resolve(t,e)}}function ot(t={}){return new at(t).toEntry()}function ht(t,e={},s){return new ct(t,{...e},s).yupSchema}function lt(t){return t===Object(t)}class ct extends m{constructor(t,e={},s){super(e),this.init(t,e,s)}init(t,e,s){e.buildYup=ht,e.createYupSchemaEntry=e.createYupSchemaEntry||ot,this.config=Object.assign(this.config,e),this.schema=t;const r=this.getType(t),i=this.getProps(t);if(this.parentNode=s,this.type=r,this.properties={...i},this.additionalProps=this.getAdditionalProperties(t),this.required=this.getRequired(t),this.setLocale(),("function"==typeof e.init?e.init:()=>{}).bind(this)(t,e),!function(t){return t&&"object"===t}(r))return void this.error(`invalid schema: must be type: "object", was type: ${r}`);if(!lt(i)){const t=JSON.stringify(a);return void this.error(`invalid schema: must have a properties object: ${t}`)}const n=this.getName(t),a=(e.buildProperties||this.buildProperties).bind(this)(t,this),o=this.propsToShape({properties:a,name:n,config:e});this.shapeConfig=o,this.validSchema=!0}get validator(){return a}setLocale(){this.config.locale&&a.setLocale(this.config.locale)}getAdditionalProperties(t){return t.additionalProperties}getRequired(t){const{getRequired:e}=this.config;return e?e(t):t.required||[]}getProps(t){return this.config.getProps(t)}getType(t){return this.config.getType(t)}getName(t){return this.config.getName(t)}get yupSchema(){return a.object().shape(this.shapeConfig)}buildProperties(){const t=Object.keys(this.properties),e=(this.config.buildProp||this.buildProp).bind(this);return t.reduce(e,{})}getRequiredPropsList(){return Array.isArray(this.required)?[...this.required]:[]}buildProp(t,e){const s=this.properties[e],r=this.getRequiredPropsList();return(this.config.setRequired||this.setRequired).bind(this)(s,e,r),(this.config.setPropEntry||this.setPropEntry).bind(this)(t,e,s),t}setRequired(t,e,s){const r=s.indexOf(e)>=0;return lt(t)||this.warn(`Bad property value: ${t} must be an object`),t.required=this.isRequired(t)||r,t}setPropEntry(t,e,s){t[e]={required:s.required,...s}}isRequired(t){return this.config.isRequired(t)}propsToShape(t={}){const e=this.objPropsToShape(t);return this.objPropsShape=e,this.addPropsShape=this.additionalPropsToShape(t,e),e}additionalPropsToShape(t,e){return e}objPropsToShape({name:t}){const e={...this.properties};return Object.keys(e).reduce((s,r)=>{const i={name:t,key:r,value:e[r]},n=this.propToYupSchemaEntry(i);return this.logInfo("propsToShape",{...i,yupSchemaEntry:n}),n&&(s[r]=n),s},{})}propToYupSchemaEntry({name:t,key:e,value:s={}}){return this.createYupSchemaEntry({schema:this.schema,parentNode:this.parentNode||this,name:t,key:e,value:s,config:this.config,builder:this})}createYupSchemaEntry(t={}){return this.config.createYupSchemaEntry(t)}onConstraintAdded(t){this.logInfo("Constraint Added",t)}}const ut={alphanumeric:{optsKey:"locale"},alpha:{optsKey:"locale"},ascii:{},byte:{},creditCard:{},currency:{opts:"currencyOpts"},dataUri:{},dateTime:{},date:{},domainName:{opts:"domainOpts"},hash:{opts:"hashAlgo"},hexColor:{},ipv4:{},ipv6:{},isbn:{},magnetUri:{},mimeType:{},mobilePhone:{},mongoId:{},postalCode:{},uuid:{}},dt={createValidatorName:(t,e)=>`is${t=(t=(t=l.default(t||e)).replace(/Uri$/,"URI")).replace(/Id$/,"ID")}`,createTestName:(t,e)=>h.default(t||e)},pt={isMagnetURI:(t,e)=>/magnet:\?xt=urn:[a-z0-9]+:[a-z0-9]{32}/i.test(t)};exports.ConstraintBuilder=w,exports.ErrorMessageHandler=E,exports.PropertyValueResolver=it,exports.YupBuilder=ct,exports.YupSchemaEntry=at,exports.YupSchemaEntryError=nt,exports.buildYup=ht,exports.createPropertyValueResolver=rt,exports.createYupSchemaEntry=ot,exports.extendYupApi=function({constraints:e,override:s=!1,validator:r,createValidatorName:i,createTestName:n}={}){if(!r)throw"extendYupApi: missing validator option";Array.isArray(e)&&(e=((t,e={})=>t.reduce((t,s)=>{if("string"!=typeof s&&!(s instanceof Object)){if(!1!==e.throws)throw`toConstraintsMap: invalid entry ${s}`;return t}if("string"==typeof s)t[name]={};else{if(!s.name){if(!1!==e.throws)throw`toConstraintsMap: invalid entry ${s} missing name`;return t}t[s.name]=s}return t},{}))(e)),e=s?e||ut:{...ut,...e||{}},i=i||dt.createValidatorName,n=n||dt.createTestName,Object.keys(e).map(s=>{let{testName:a,optsKey:o,validatorName:h,logging:l}=e[s];const c=i(h,s);a=n(a,s),t.addMethod(t.string,s,(e={})=>{const{message:i}=e,n=e[o];return t.string().test(a,i,t=>{const{path:e,createError:o}=this;let h=r[c];if(h=h||pt[c],"function"!=typeof h)throw Error("No method named ${validatorName} on validator");const u=h(t,n);return!0===l&&console.log("Yup validator bridge",{key:s,fullValidatorName:c,testName:a,value:t,valid:u}),u||o({path:e,message:i})})})})},exports.types=X; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "schema-to-yup", | ||
"version": "1.11.13", | ||
"version": "1.11.14", | ||
"publishConfig": { | ||
@@ -5,0 +5,0 @@ "access": "public" |
268
Readme.md
@@ -1,6 +0,75 @@ | ||
# Schema to Yup schema | ||
<!-- vscode-markdown-toc --> | ||
- 1. [Schemas](#Schemas) | ||
- 1.1. [JSON schema](#JSONschema) | ||
- 1.2. [GraphQL schema](#GraphQLschema) | ||
- 1.3. [Avro schema](#Avroschema) | ||
- 1.4. [Custom/Alternative schemas](#CustomAlternativeschemas) | ||
- 2. [Custom/Alternative validators](#CustomAlternativevalidators) | ||
- 3. [Customization hooks](#Customizationhooks) | ||
- 4. [Build and Sample run](#BuildandSamplerun) | ||
- 5. [Quick start](#Quickstart) | ||
- 5.1. [Refs](#Refs) | ||
- 5.2. [Mode](#Mode) | ||
- 5.3. [Shape](#Shape) | ||
- 6. [Types](#Types) | ||
- 6.1. [Mixed (any type)](#Mixedanytype) | ||
- 6.2. [Reference constraints](#Referenceconstraints) | ||
- 6.3. [Array](#Array) | ||
- 6.4. [Boolean](#Boolean) | ||
- 6.5. [Date](#Date) | ||
- 6.6. [Number](#Number) | ||
- 6.7. [Object](#Object) | ||
- 6.8. [String](#String) | ||
- 7. [Confirm password](#Confirmpassword) | ||
- 8. [Multi-type constraints](#Multi-typeconstraints) | ||
- 9. [Custom builder](#Custombuilder) | ||
- 10. [Custom builder functions](#Custombuilderfunctions) | ||
- 10.1. [Custom init](#Custominit) | ||
- 10.2. [Custom buildProperties](#CustombuildProperties) | ||
- 10.3. [Custom buildProp](#CustombuildProp) | ||
- 10.4. [Custom setRequired](#CustomsetRequired) | ||
- 10.5. [Custom setPropEntry](#CustomsetPropEntry) | ||
- 11. [Custom entry builders](#Customentrybuilders) | ||
- 11.1. [Custom type handlers](#Customtypehandlers) | ||
- 11.1.1. [Custom array type handler](#Customarraytypehandler) | ||
- 11.2. [Additional type handlers](#Additionaltypehandlers) | ||
- 11.3. [Custom constraint handler functions](#Customconstrainthandlerfunctions) | ||
- 11.4. [Custom constraint builder](#Customconstraintbuilder) | ||
- 12. [Supporting alternative validators](#Supportingalternativevalidators) | ||
- 13. [Conditional logic](#Conditionallogic) | ||
- 13.1. [Customizing conditional logic](#Customizingconditionallogic) | ||
- 14. [Additional properties](#Additionalproperties) | ||
- 15. [Complex example](#Complexexample) | ||
- 15.1. [Complex/Nested schemas](#ComplexNestedschemas) | ||
- 16. [Custom models](#Custommodels) | ||
- 16.1. [GraphQL schema](#GraphQLschema-1) | ||
- 17. [Other/custom schema format support](#Othercustomschemaformatsupport) | ||
- 17.1. [Custom logs and error handling](#Customlogsanderrorhandling) | ||
- 18. [Localized error messages](#Localizederrormessages) | ||
- 19. [Customization](#Customization) | ||
- 19.1. [Customization example](#Customizationexample) | ||
- 19.2. [Extend Yup API to bridge other validators](#ExtendYupAPItobridgeothervalidators) | ||
- 19.3. [Subclassing](#Subclassing) | ||
- 19.4. [Error messages](#Errormessages) | ||
- 19.5. [Error message handling](#Errormessagehandling) | ||
- 19.5.1. [Use a custom error message handler](#Useacustomerrormessagehandler) | ||
- 19.6. [Custom validation messages using select defaults](#Customvalidationmessagesusingselectdefaults) | ||
- 20. [Adding custom constraints](#Addingcustomconstraints) | ||
- 21. [Similar projects](#Similarprojects) | ||
- 22. [Testing](#Testing) | ||
- 23. [Development](#Development) | ||
- 24. [Ideas and suggestions](#Ideasandsuggestions) | ||
- 25. [Author](#Author) | ||
- 26. [License](#License) | ||
<!-- vscode-markdown-toc-config | ||
numbering=true | ||
autoSave=true | ||
/vscode-markdown-toc-config --> | ||
<!-- /vscode-markdown-toc --># Schema to Yup schema | ||
Build a Yup schema from a JSON Schema, GraphQL schema (type definition) or any other similar type/class and field/properties model or schema :) | ||
## Schemas | ||
## 1. <a name='Schemas'></a>Schemas | ||
@@ -12,3 +81,3 @@ - JSON | ||
### JSON schema | ||
### 1.1. <a name='JSONschema'></a>JSON schema | ||
@@ -20,11 +89,11 @@ - [AJV: JSON Schema keywords](https://ajv.js.org/keywords.html) | ||
### GraphQL schema | ||
### 1.2. <a name='GraphQLschema'></a>GraphQL schema | ||
GraphQL type definition exports using [graphSchemaToJson](https://github.com/kristianmandrup/graphSchemaToJson) (see [GraphQL schema](#graphql-schema)). | ||
### Avro schema | ||
### 1.3. <a name='Avroschema'></a>Avro schema | ||
Recently basic [Avro](https://avro.apache.org/docs/current/spec.html) schema support has been added as well. | ||
### Custom/Alternative schemas | ||
### 1.4. <a name='CustomAlternativeschemas'></a>Custom/Alternative schemas | ||
@@ -37,7 +106,7 @@ You can easily add support for your own custom schema formats. | ||
## Custom/Alternative validators | ||
## 2. <a name='CustomAlternativevalidators'></a>Custom/Alternative validators | ||
You can use the building blocks of this library to support alternative validators other than Yup. See [Supporting alternative validators](#supporting-alternative-validators) | ||
## Customization hooks | ||
## 3. <a name='Customizationhooks'></a>Customization hooks | ||
@@ -54,3 +123,3 @@ This library is built to be easy to customize or extend to suit individual developer needs. | ||
## Build and Sample run | ||
## 4. <a name='BuildandSamplerun'></a>Build and Sample run | ||
@@ -75,3 +144,3 @@ `$ yarn run build` | ||
## Quick start | ||
## 5. <a name='Quickstart'></a>Quick start | ||
@@ -159,3 +228,3 @@ Install | ||
### Refs | ||
### 5.1. <a name='Refs'></a>Refs | ||
@@ -169,3 +238,3 @@ Please note that this library does not currently resolve `$ref` (JSON Pointers) out of the box. You can use another library for that. | ||
### Mode | ||
### 5.2. <a name='Mode'></a>Mode | ||
@@ -221,3 +290,3 @@ By default, any property will be explicitly `notRequired` unless set to be required, either via `required: true` in the property constraint object or via the `required` list of properties of the `object` schema definition (of the property). | ||
### Shape | ||
### 5.3. <a name='Shape'></a>Shape | ||
@@ -236,3 +305,3 @@ You can access the internal Yup shape, via `shapeConfig` on the yup schema returned by the `buildYup` schema builder function. | ||
## Types | ||
## 6. <a name='Types'></a>Types | ||
@@ -248,3 +317,3 @@ Currently the following schema types are supported: | ||
### Mixed (any type) | ||
### 6.1. <a name='Mixedanytype'></a>Mixed (any type) | ||
@@ -264,3 +333,3 @@ - `strict` | ||
### Reference constraints | ||
### 6.2. <a name='Referenceconstraints'></a>Reference constraints | ||
@@ -296,3 +365,3 @@ Reference constraints within the schema can be defined as follows: | ||
### Array | ||
### 6.3. <a name='Array'></a>Array | ||
@@ -306,7 +375,7 @@ - `ensure` | ||
### Boolean | ||
### 6.4. <a name='Boolean'></a>Boolean | ||
No keys | ||
### Date | ||
### 6.5. <a name='Date'></a>Date | ||
@@ -316,3 +385,3 @@ - `maxDate` (`max`) | ||
### Number | ||
### 6.6. <a name='Number'></a>Number | ||
@@ -329,3 +398,3 @@ - `integer` | ||
### Object | ||
### 6.7. <a name='Object'></a>Object | ||
@@ -336,3 +405,3 @@ - `camelCase` | ||
### String | ||
### 6.8. <a name='String'></a>String | ||
@@ -352,3 +421,3 @@ - `minLength` (`min`) | ||
## Confirm password | ||
## 7. <a name='Confirmpassword'></a>Confirm password | ||
@@ -370,3 +439,3 @@ You can use the special `refValue` constraint for password confirmation scenarios. | ||
## Multi-type constraints | ||
## 8. <a name='Multi-typeconstraints'></a>Multi-type constraints | ||
@@ -377,3 +446,3 @@ A sample implementation to support multi type constraints has been implemented in `MultiPropertyValueResolver`. | ||
## Custom builder | ||
## 9. <a name='Custombuilder'></a>Custom builder | ||
@@ -398,3 +467,3 @@ To customize the builder to suit your needs, simply subclass the `YupBuilder` class and create your own factory function which instantiates your subclass. | ||
## Custom builder functions | ||
## 10. <a name='Custombuilderfunctions'></a>Custom builder functions | ||
@@ -407,3 +476,3 @@ - `init` | ||
### Custom init | ||
### 10.1. <a name='Custominit'></a>Custom init | ||
@@ -423,3 +492,3 @@ You can supply a custom `init` function on the `config` object to do custom initialization. The `init` function will be bound to the `YupBuilder` instance so that `this` returns the builder instance. | ||
### Custom buildProperties | ||
### 10.2. <a name='CustombuildProperties'></a>Custom buildProperties | ||
@@ -436,3 +505,3 @@ You can override the built-in `buildProperties` method (see code below) by supplying a custom `buildProperties` function on the `config` object. | ||
### Custom buildProp | ||
### 10.3. <a name='CustombuildProp'></a>Custom buildProp | ||
@@ -455,3 +524,3 @@ You can override the built-in `buildProp` method (see code below) by supplying a custom `buildProp` function on the `config` object. | ||
### Custom setRequired | ||
### 10.4. <a name='CustomsetRequired'></a>Custom setRequired | ||
@@ -472,3 +541,3 @@ You can override the built-in `setRequired` method (see code below) by supplying a custom `setRequired` function on the `config` object. | ||
### Custom setPropEntry | ||
### 10.5. <a name='CustomsetPropEntry'></a>Custom setPropEntry | ||
@@ -487,3 +556,3 @@ You can override the built-in `setPropEntry` method (see code below) by supplying a custom `setPropEntry` function on the `config` object. | ||
## Custom entry builders | ||
## 11. <a name='Customentrybuilders'></a>Custom entry builders | ||
@@ -508,3 +577,3 @@ You can pass in custom functions for the following kinds of type entry values | ||
### Custom type handlers | ||
### 11.1. <a name='Customtypehandlers'></a>Custom type handlers | ||
@@ -534,4 +603,43 @@ You can pass any custom type handlers in a `typeHandlers` object as part of the `config` object passes. See `setTypeHandlers()` and `get typeHandlers()` in `entry.js` for how this works internally. | ||
#### Custom array type handler | ||
The following is the "Generic" TypeHandler (ie. `YupMixed`) which is the base class for all built-in type handlers. | ||
```js | ||
class GenericTypeHandler { | ||
constructor(opts = {}) { | ||
super(opts.config); | ||
this.init(opts); | ||
} | ||
init(opts) { | ||
let { schema, key, value, config, entryHandler } = opts; | ||
// ... | ||
this.key = key; | ||
this.schema = schema; | ||
this.properties = schema.properties || {}; | ||
this.value = value; | ||
this.typeConstraintObj = this.value; | ||
this.title = value.title; | ||
this.description = value.description; | ||
this.constraints = this.getConstraints(); | ||
this.format = value.format || this.constraints.format; | ||
this.config = config || {}; | ||
this.type = this.baseType; | ||
// ... | ||
} | ||
// ... | ||
} | ||
``` | ||
The `constraints` property contains the type constraint object, the `value` contains the raw constraints. | ||
You will need to at minimum implement a `validatorInstance` getter or property, such as: | ||
```js | ||
get validatorInstance() { | ||
return yup | ||
} | ||
``` | ||
#### 11.1.1. <a name='Customarraytypehandler'></a>Custom array type handler | ||
Currently this library has minimal support for the `array` type. To add better `array` type support, create a custom type handler for handling array types and use it as follows. | ||
@@ -551,3 +659,3 @@ | ||
### Additional type handlers | ||
### 11.2. <a name='Additionaltypehandlers'></a>Additional type handlers | ||
@@ -577,3 +685,3 @@ In order to pass a a type handler map that does not rely on any built in type handlers, pass in a `types` object | ||
### Custom constraint handler functions | ||
### 11.3. <a name='Customconstrainthandlerfunctions'></a>Custom constraint handler functions | ||
@@ -665,3 +773,3 @@ You can add custom constraint handler functions directly via the `config` object. | ||
### Custom constraint builder | ||
### 11.4. <a name='Customconstraintbuilder'></a>Custom constraint builder | ||
@@ -714,3 +822,3 @@ This library supports using a custom constraint builder to add and build constraints. All factories are initialized in `initHelpers` and executed as the first step of `convert` (see `mixed.js`) | ||
## Supporting alternative validators | ||
## 12. <a name='Supportingalternativevalidators'></a>Supporting alternative validators | ||
@@ -804,3 +912,3 @@ Supply a `validator` instance (or getter function) on the `config` object which returns an instance of the validator you wish to use. | ||
## Conditional logic | ||
## 13. <a name='Conditionallogic'></a>Conditional logic | ||
@@ -865,3 +973,3 @@ Basic support for [when conditions](https://github.com/jquense/yup#mixedwhenkeys-string--arraystring-builder-object--value-schema-schema-schema) as requested and outlined in [this issue](https://github.com/kristianmandrup/schema-to-yup/issues/14) is now included. | ||
### Customizing conditional logic | ||
### 13.1. <a name='Customizingconditionallogic'></a>Customizing conditional logic | ||
@@ -886,3 +994,3 @@ You can now also override, extend or customize the `when` condition logic by passing in your own factory method for the config object entry `createWhenCondition` | ||
## Additional properties | ||
## 14. <a name='Additionalproperties'></a>Additional properties | ||
@@ -923,3 +1031,3 @@ Currently this library does not have built-in support for the `additionalProperties` feature of JSON schema as described [here](https://json-schema.org/understanding-json-schema/reference/object.html) | ||
## Complex example | ||
## 15. <a name='Complexexample'></a>Complex example | ||
@@ -999,3 +1107,3 @@ Here a more complete example of the variations currently possible | ||
### Complex/Nested schemas | ||
### 15.1. <a name='ComplexNestedschemas'></a>Complex/Nested schemas | ||
@@ -1006,3 +1114,3 @@ Nested object schema properties are supported. | ||
## Custom models | ||
## 16. <a name='Custommodels'></a>Custom models | ||
@@ -1033,3 +1141,3 @@ This library now also supports non JSON schema models. See the `types/schema-parser-maps` mappings. | ||
### GraphQL schema | ||
### 16.1. <a name='GraphQLschema-1'></a>GraphQL schema | ||
@@ -1105,3 +1213,3 @@ To support another model, such as GraphQL schema (type definitions) via [graphSchemaToJson](https://github.com/kristianmandrup/graphSchemaToJson) | ||
## Other/custom schema format support | ||
## 17. <a name='Othercustomschemaformatsupport'></a>Other/custom schema format support | ||
@@ -1141,3 +1249,3 @@ You can supply a `config.schemaParserMap` object with parser entries for any specific schema formats you wish to support. | ||
### Custom logs and error handling | ||
### 17.1. <a name='Customlogsanderrorhandling'></a>Custom logs and error handling | ||
@@ -1197,3 +1305,3 @@ You can enable logging py passing a `log` option in the `config.enable` object. If set to `true`, it will by default assign the internal log function to `console.log` | ||
## Localized error messages | ||
## 18. <a name='Localizederrormessages'></a>Localized error messages | ||
@@ -1205,3 +1313,3 @@ You can specify the locale to use in the `config` object. | ||
## Customization | ||
## 19. <a name='Customization'></a>Customization | ||
@@ -1213,3 +1321,3 @@ You can supply a `createYupSchemaEntry` function as an entry in the `config` object. | ||
### Customization example | ||
### 19.1. <a name='Customizationexample'></a>Customization example | ||
@@ -1242,3 +1350,3 @@ ```js | ||
### Extend Yup API to bridge other validators | ||
### 19.2. <a name='ExtendYupAPItobridgeothervalidators'></a>Extend Yup API to bridge other validators | ||
@@ -1288,3 +1396,3 @@ You can use `extendYupApi` to extend the Yup API with extra validation methods: | ||
### Subclassing | ||
### 19.3. <a name='Subclassing'></a>Subclassing | ||
@@ -1305,3 +1413,3 @@ You can sublass `YupBuilder` or any of the internal classes to create your own custom infrastructure to suit your particular needs, extend with extra features etc. | ||
### Error messages | ||
### 19.4. <a name='Errormessages'></a>Error messages | ||
@@ -1376,4 +1484,36 @@ You can pass an `errMessages` object in the optional `config` object argument with key mappings for your custom validation error messages. | ||
### Error message handling | ||
### Custom error functions | ||
You can also add custom error functions at a granular level with access to `constraints`, `key` , `title`, `description`, `parentNode` and `typeHandler` | ||
````js | ||
const message2 = { | ||
title: "users", | ||
type: "object", | ||
required: ["amazon"], | ||
properties: { | ||
amazon: { type: "string", pattern: /(foo|bar)/, title: "amazonas" }, | ||
}, | ||
}; | ||
const config = { | ||
errMessages: { | ||
amazon: { | ||
pattern: (constraints, { title, parentNode }) => | ||
`Pattern must be ${constraints.pattern} for ${title} of ${parentNode.title}`, | ||
}, | ||
}, | ||
}; | ||
try { | ||
const yupSchema = buildYup(message2, config); | ||
valid = yupSchema.validateSync({ | ||
amazon: "dfds", | ||
}); | ||
} catch (e) { | ||
valid = e.errors[0]; | ||
} | ||
expect(valid).toBe("Pattern must be /(foo|bar)/ for amazonas"); | ||
}); | ||
### 19.5. <a name='Errormessagehandling'></a>Error message handling | ||
Internally the validator error messages are resolved via an instance of the `ErrorMessageHandler` calling the `validationErrorMessage` method. | ||
@@ -1390,3 +1530,3 @@ | ||
} | ||
``` | ||
```` | ||
@@ -1410,3 +1550,3 @@ Error handling | ||
#### Use a custom error message handler | ||
#### 19.5.1. <a name='Useacustomerrormessagehandler'></a>Use a custom error message handler | ||
@@ -1530,3 +1670,3 @@ For simple cases, you can use the `config` object to pass your own custom `validationErrorMessage` function. In the example below we expand the default function to use `value.errors` if present on the entry type value object (similar to `errMessage` above). | ||
### Custom validation messages using select defaults | ||
### 19.6. <a name='Customvalidationmessagesusingselectdefaults'></a>Custom validation messages using select defaults | ||
@@ -1551,3 +1691,3 @@ ```js | ||
## Adding custom constraints | ||
## 20. <a name='Addingcustomconstraints'></a>Adding custom constraints | ||
@@ -1659,3 +1799,3 @@ See the `number` type for the current best practice to add type constraints. | ||
## Similar projects | ||
## 21. <a name='Similarprojects'></a>Similar projects | ||
@@ -1672,3 +1812,3 @@ - [JSON schema to Elastic Search mapping](https://github.com/kristianmandrup/json-schema-to-es-mapping) | ||
## Testing | ||
## 22. <a name='Testing'></a>Testing | ||
@@ -1681,15 +1821,15 @@ Uses [jest](jestjs.io/) for unit testing. | ||
## Development | ||
## 23. <a name='Development'></a>Development | ||
A new version is under development at [schema-to-yup-mono](https://github.com/kristianmandrup/schema-to-yup-mono) which is this code ported to a lerna monorepo with a cleaner, mode modular structyure. More work needs to be done in terms of TDD and unit testing. Ideally this repo should be ported to [Nx](https://nx.dev/) | ||
## Ideas and suggestions | ||
## 24. <a name='Ideasandsuggestions'></a>Ideas and suggestions | ||
Please feel free to come with ideas and suggestions on how to further improve this library. | ||
## Author | ||
## 25. <a name='Author'></a>Author | ||
2018 Kristian Mandrup (CTO@Tecla5) | ||
## License | ||
## 26. <a name='License'></a>License | ||
@@ -1696,0 +1836,0 @@ MIT |
@@ -8,5 +8,6 @@ import { Base } from "./types"; | ||
super(config); | ||
const { value, type, kind, name, key, schema, types } = opts; | ||
const { value, type, kind, name, key, schema, types, parentNode } = opts; | ||
// this.logInfo('BasePropertyValueResolver', opts) | ||
this.entryHandler = entryHandler || opts.entryHandler; | ||
this.parentNode = parentNode; | ||
this.builder = opts.builder; | ||
@@ -41,5 +42,7 @@ this.opts = opts; | ||
get obj() { | ||
const { schema, key, value, type, kind, config, entryHandler } = this; | ||
const { schema, key, value, type, kind, config, entryHandler, parentNode } = | ||
this; | ||
return { | ||
schema, | ||
parentNode, | ||
key, | ||
@@ -54,2 +57,1 @@ value, | ||
} | ||
@@ -1,4 +0,3 @@ | ||
import { YupMixed } from "./types/mixed"; | ||
import { TypeMatcher } from "./types/_type-matcher"; | ||
import * as Yup from 'yup' | ||
export class ConstraintBuilder extends TypeMatcher { | ||
@@ -5,0 +4,0 @@ constructor(typeHandler, config = {}) { |
@@ -8,3 +8,3 @@ import { | ||
toYupObject, | ||
toYupDate | ||
toYupDate, | ||
} from "./types"; | ||
@@ -19,4 +19,5 @@ | ||
super(opts.config); | ||
const { schema, name, key, value, config, builder } = opts; | ||
this.builder = builder | ||
const { schema, name, key, value, config, builder, parentNode } = opts; | ||
this.parentNode = parentNode; | ||
this.builder = builder; | ||
this.opts = opts; | ||
@@ -27,8 +28,8 @@ this.schema = schema; | ||
this.config = config || {}; | ||
this.name = name; | ||
this.init() | ||
this.name = name; | ||
this.init(); | ||
} | ||
get calcType() { | ||
const { value } = this | ||
const { value } = this; | ||
return Array.isArray(value) ? "array" : value.type; | ||
@@ -46,3 +47,3 @@ } | ||
init() { | ||
this.type = this.calcType; | ||
this.type = this.calcType; | ||
this.kind = this.calcKind; | ||
@@ -54,8 +55,8 @@ this.setTypeHandlers(); | ||
get validator() { | ||
return this.builder && this.builder.validator | ||
return this.builder && this.builder.validator; | ||
} | ||
setPropertyHandler() { | ||
const { config } = this | ||
const opts = this.propertyHandlerOpts | ||
const { config } = this; | ||
const opts = this.propertyHandlerOpts; | ||
const createPropertyValueHandlerFn = | ||
@@ -67,5 +68,6 @@ config.createPropertyValueHandler || this.createPropertyValueHandler; | ||
get propertyHandlerOpts() { | ||
const { types, value, name, key, type, kind, schema } = this; | ||
const { types, value, name, key, type, kind, schema, parentNode } = this; | ||
return { | ||
type, | ||
parentNode, | ||
kind, | ||
@@ -77,3 +79,3 @@ types, | ||
schema, | ||
entryHandler: this | ||
entryHandler: this, | ||
}; | ||
@@ -93,3 +95,3 @@ } | ||
object: toYupObject, | ||
date: toYupDate | ||
date: toYupDate, | ||
}; | ||
@@ -99,3 +101,3 @@ } | ||
setTypeHandlers() { | ||
this.types = this.config.types || this.typeHandlers | ||
this.types = this.config.types || this.typeHandlers; | ||
} | ||
@@ -106,3 +108,3 @@ | ||
...this.defaultTypeHandlerMap, | ||
...(this.config.typeHandlers || {}) | ||
...(this.config.typeHandlers || {}), | ||
}; | ||
@@ -109,0 +111,0 @@ } |
@@ -7,44 +7,55 @@ import { TypeMatcher } from "./types/_type-matcher"; | ||
this.typeHandler = typeHandler; | ||
this.init() | ||
this.init(); | ||
} | ||
init() { | ||
const { typeHandler } = this | ||
const { typeHandler } = this; | ||
this.constraints = typeHandler.constraints; | ||
this.errMessages = typeHandler.errMessages; | ||
this.key = typeHandler.key; | ||
this.value = typeHandler.value; // raw type constraints | ||
this.constraints = typeHandler.constraints; // type constraints (possibly filtered) | ||
this.parentNode = typeHandler.parentNode; | ||
this.type = typeHandler.type; | ||
this.description = typeHandler.description | ||
this.title = typeHandler.title | ||
this.setErrMessage() | ||
this.description = typeHandler.description; | ||
this.title = typeHandler.title; | ||
this.setErrMessage(); | ||
} | ||
errMessageMap(value = {}) { | ||
const key = this.errMessagesMapKey | ||
return value[key] || this.errMessages | ||
const key = this.errMessagesMapKey; | ||
return value[key] || this.errMessages; | ||
} | ||
get errMessageKey() { | ||
return this.config.errMessageKey || 'errMessage' | ||
return this.config.errMessageKey || "errMessage"; | ||
} | ||
get errMessagesMapKey() { | ||
return this.config.errMessagesMapKey || 'errMessages' | ||
return this.config.errMessagesMapKey || "errMessages"; | ||
} | ||
setErrMessage() { | ||
const { typeHandler } = this | ||
const { value } = typeHandler | ||
if (!value.errMessage) return | ||
const valueKey = this.errMessageKey | ||
const errMessageMap = this.errMessageMap(value) | ||
errMessageMap[this.key] = value[valueKey] || errMessageMap[this.key] | ||
return this | ||
const { typeHandler } = this; | ||
const { value } = typeHandler; | ||
if (!value.errMessage) return; | ||
const valueKey = this.errMessageKey; | ||
const errMessageMap = this.errMessageMap(value); | ||
errMessageMap[this.key] = value[valueKey] || errMessageMap[this.key]; | ||
return this; | ||
} | ||
validationErrorMessage(msgName) { | ||
const { constraints, description, title } = this; | ||
const { constraints, key, description, title, typeHandler, parentNode } = | ||
this; | ||
const errMsg = this.errMessageFor(msgName); | ||
return typeof errMsg === "function" ? errMsg(constraints, { description, title}) : errMsg; | ||
return typeof errMsg === "function" | ||
? errMsg(constraints, { | ||
key, | ||
title, | ||
description, | ||
typeHandler, | ||
parentNode, | ||
}) | ||
: errMsg; | ||
} | ||
@@ -51,0 +62,0 @@ |
@@ -19,7 +19,15 @@ import { BasePropertyValueResolver } from "./base-property-value-resolver"; | ||
config.createMultiTypeResolver || this.createMultiTypeResolver.bind(this); | ||
this.multiTypeResolver = createMultiTypeResolverFn(opts, config, entryHandler); | ||
this.multiTypeResolver = createMultiTypeResolverFn( | ||
opts, | ||
config, | ||
entryHandler | ||
); | ||
const createSingleTypeResolverFn = | ||
config.createSingleTypeResolver || | ||
this.createSingleTypeResolver.bind(this); | ||
this.singleTypeResolver = createSingleTypeResolverFn(opts, config, entryHandler); | ||
this.singleTypeResolver = createSingleTypeResolverFn( | ||
opts, | ||
config, | ||
entryHandler | ||
); | ||
} | ||
@@ -61,3 +69,4 @@ | ||
this.error("toEntry: unknown type", this.type); | ||
return false; | ||
} | ||
} |
@@ -17,3 +17,3 @@ import { Constraint } from '../constraints/base'; | ||
isValidConstraint(date) { | ||
return this.isDateLike(date); | ||
return this.isDateLike(date) || this.typeHandler.isStringType(value);; | ||
} | ||
@@ -20,0 +20,0 @@ |
import { YupMixed } from "../mixed"; | ||
import * as Yup from 'yup' | ||
@@ -31,4 +32,6 @@ export class YupDate extends YupMixed { | ||
// TODO: use Yup.ref if string and not a date format | ||
toDate(date) { | ||
return new Date(date); | ||
const isDateRef = this.isStringType(date) && !this.isValidDateFormat(date) | ||
return isDateRef ? Yup.ref(date) : new Date(date) | ||
} | ||
@@ -44,5 +47,16 @@ | ||
if (!this.isValidDateType(date)) return false; | ||
return this.isStringType(date) ? Boolean(Date.parse(date)) : true; | ||
// const parsedDate = Date.parse(date) | ||
// const validDateFormat = Boolean(parsedDate) | ||
return true// this.isStringType(date) ? validDateFormat : true; | ||
} | ||
isValidDateFormat(date) { | ||
try { | ||
const parsedDate = Date.parse(date) | ||
return Boolean(parsedDate) | ||
} catch (e) { | ||
return false | ||
} | ||
} | ||
// optionally transform millisecs to Date value? | ||
@@ -49,0 +63,0 @@ transformToDate(date) { |
@@ -12,5 +12,11 @@ import { YupDate } from "./date"; | ||
isDateCompatible(obj) { | ||
return this.config.isString(obj); | ||
} | ||
handle(obj) { | ||
return this.isDate(obj) && YupDate.create(obj).createSchemaEntry(); | ||
return YupDate.create(obj).createSchemaEntry(); | ||
// return this.isDate(obj) && YupDate.create(obj).createSchemaEntry(); | ||
// return this.isDateCompatible(obj) && YupDate.create(obj).createSchemaEntry(); | ||
} | ||
} |
@@ -18,13 +18,14 @@ import * as yup from "yup"; | ||
super(opts.config); | ||
this.init(opts) | ||
this.init(opts); | ||
} | ||
init(opts) { | ||
let { schema, key, value, config, entryHandler } = opts; | ||
let { schema, key, value, config, entryHandler, parentNode } = opts; | ||
config = config || {}; | ||
schema = schema || {}; | ||
this.parentNode = parentNode || entryHandler.parentNode; | ||
this.validateOnCreate(key, value, opts); | ||
this.opts = opts | ||
this.entryHandler = entryHandler | ||
this.validator = this.getValidator() | ||
this.opts = opts; | ||
this.entryHandler = entryHandler; | ||
this.validator = this.getValidator(); | ||
this.key = key; | ||
@@ -34,4 +35,4 @@ this.schema = schema; | ||
this.value = value; | ||
this.title = value.title | ||
this.description = value.description | ||
this.title = value.title; | ||
this.description = value.description; | ||
this.constraints = this.getConstraints(); | ||
@@ -42,11 +43,11 @@ this.format = value.format || this.constraints.format; | ||
this.mixedConfig = this.config.mixedEnabled || {}; | ||
this.typeConfig = this.config[this.type] || {}; | ||
this.typeConfig = this.config[this.type] || {}; | ||
this.errMessages = config.errMessages || {}; | ||
this.configureTypeConfig(); | ||
this.constraintsAdded = {}; | ||
this.base = this.getBase() | ||
this.base = this.getBase(); | ||
} | ||
get builder() { | ||
return this.entryHandler && this.entryHandler.builder | ||
return this.entryHandler && this.entryHandler.builder; | ||
} | ||
@@ -57,10 +58,15 @@ | ||
} | ||
get customBaseValidator() { | ||
return this.config.validatorFor && this.config.validatorFor(this.type) | ||
return this.config.validatorFor && this.config.validatorFor(this.type); | ||
} | ||
getValidator() { | ||
return this.opts.validator || this.config.validator || (this.builder && this.builder.validator) || yup; | ||
} | ||
return ( | ||
this.opts.validator || | ||
this.config.validator || | ||
(this.builder && this.builder.validator) || | ||
yup | ||
); | ||
} | ||
@@ -100,3 +106,3 @@ get baseType() { | ||
const modeEntry = this.mode[modeName]; | ||
return !!this.disableFlags.find(disable => modeEntry === disable); | ||
return !!this.disableFlags.find((disable) => modeEntry === disable); | ||
} | ||
@@ -106,3 +112,3 @@ | ||
const modeEntry = this.mode[modeName]; | ||
return !!this.enableFlags.find(disable => modeEntry === disable); | ||
return !!this.enableFlags.find((disable) => modeEntry === disable); | ||
} | ||
@@ -120,3 +126,3 @@ | ||
...value, | ||
notRequired: true | ||
notRequired: true, | ||
}; | ||
@@ -159,3 +165,3 @@ } | ||
rebind(...methods) { | ||
methods.map(name => { | ||
methods.map((name) => { | ||
const method = this[name]; | ||
@@ -187,3 +193,3 @@ this[name] = this.isFunctionType(method) ? method.bind(this) : method; | ||
"const", | ||
"refValueFor" | ||
"refValueFor", | ||
] | ||
@@ -218,3 +224,3 @@ ); | ||
convertEnabled() { | ||
this.enabled.map(name => { | ||
this.enabled.map((name) => { | ||
const convertFn = this.convertFnFor(name); | ||
@@ -228,3 +234,5 @@ if (convertFn) { | ||
convertFnFor(name) { | ||
return this.customConvertFnFor(name, this) || this.builtInConvertFnFor(name); | ||
return ( | ||
this.customConvertFnFor(name, this) || this.builtInConvertFnFor(name) | ||
); | ||
} | ||
@@ -257,18 +265,23 @@ | ||
apply(fnName, ...fnArgs) { | ||
if (typeof fnName !== 'string') { | ||
throw new TypeError(`[Mixed] apply must take a method name available on the validator instance as first argument`) | ||
if (typeof fnName !== "string") { | ||
throw new TypeError( | ||
`[Mixed] apply must take a method name available on the validator instance as first argument` | ||
); | ||
} | ||
this.base = (fnArgs && fnArgs.length && this.base[fnName](...fnArgs)) || this.base; | ||
return this | ||
this.base = | ||
(fnArgs && fnArgs.length && this.base[fnName](...fnArgs)) || this.base; | ||
return this; | ||
} | ||
applyArr(fnName, arrValue) { | ||
if (typeof fnName !== 'string') { | ||
throw new TypeError(`[Mixed] apply must take a method name available on the validator instance as first argument`) | ||
if (typeof fnName !== "string") { | ||
throw new TypeError( | ||
`[Mixed] apply must take a method name available on the validator instance as first argument` | ||
); | ||
} | ||
this.base = (arrValue && arrValue.length && this.base[fnName](arrValue)) || this.base; | ||
return this | ||
this.base = | ||
(arrValue && arrValue.length && this.base[fnName](arrValue)) || this.base; | ||
return this; | ||
} | ||
addTrueValueConstraint(propName, opts) { | ||
@@ -288,3 +301,5 @@ const constraint = this.constraintBuilder.addTrueValueConstraint( | ||
if (!this.constraintBuilder) { | ||
throw new Error(`[YupMixed] addConstraint: Missing constraintBuilder in ${this.constructor.name}`); | ||
throw new Error( | ||
`[YupMixed] addConstraint: Missing constraintBuilder in ${this.constructor.name}` | ||
); | ||
} | ||
@@ -309,8 +324,9 @@ const constraint = this.constraintBuilder.addConstraint(propName, opts); | ||
const constraintNames = constraintsMap[key]; | ||
const fnName = key === "trueValue" ? "addTrueValueConstraint" : "addConstraint"; | ||
const fnName = | ||
key === "trueValue" ? "addTrueValueConstraint" : "addConstraint"; | ||
const fn = this[fnName]; | ||
const value = this.constraints[key]; | ||
constraintNames.map(constraintName => { | ||
constraintNames.map((constraintName) => { | ||
fn(constraintName, { value }); | ||
}); | ||
}); | ||
} | ||
@@ -321,3 +337,3 @@ | ||
simple: ["default", "required", "notRequired", "nullable"], | ||
trueValue: ["strict"] | ||
trueValue: ["strict"], | ||
}; | ||
@@ -327,25 +343,29 @@ } | ||
refValueFor() { | ||
let propRefName = | ||
this.constraints.refValueFor | ||
let propRefName = this.constraints.refValueFor; | ||
if (this.isNothing(propRefName)) return this; | ||
this.logInfo("refValueFor", { propRefName }) | ||
return this.apply('when', (propRefName, (refValueFor, field) => | ||
refValueFor ? field.required().oneOf([yup.ref(propRefName)]) : field | ||
)) | ||
this.logInfo("refValueFor", { propRefName }); | ||
return this.apply( | ||
"when", | ||
(propRefName, | ||
(refValueFor, field) => | ||
refValueFor ? field.required().oneOf([yup.ref(propRefName)]) : field) | ||
); | ||
} | ||
normalizeValues(values) { | ||
return Array.isArray(values) ? values : [values]; | ||
return Array.isArray(values) ? values : [values]; | ||
} | ||
get oneOfValues() { | ||
return this.constraints.enum || this.constraints.oneOf || this.constraints.anyOf; | ||
return ( | ||
this.constraints.enum || this.constraints.oneOf || this.constraints.anyOf | ||
); | ||
} | ||
get oneOfAliases() { | ||
return ["oneOf", "enum", "anyOf"] | ||
return ["oneOf", "enum", "anyOf"]; | ||
} | ||
get oneOfAlias() { | ||
return this.oneOfAliases.find(key => { | ||
return this.oneOfAliases.find((key) => { | ||
return this.constraints[key] !== undefined; | ||
@@ -356,11 +376,16 @@ }); | ||
oneOf() { | ||
let values = this.oneOfValues | ||
let values = this.oneOfValues; | ||
if (this.isNothing(values)) return this; | ||
values = this.normalizeValues(values) | ||
const resolvedValues = this.resolveValues(values) | ||
values = this.normalizeValues(values); | ||
const resolvedValues = this.resolveValues(values); | ||
// using alias | ||
const alias = this.oneOfAlias | ||
const alias = this.oneOfAlias; | ||
// log details | ||
const idObj = { constraintName: alias, method: 'oneOf', key: this.key, type: this.type} | ||
this.logDetails('type', idObj, values, resolvedValues) | ||
const idObj = { | ||
constraintName: alias, | ||
method: "oneOf", | ||
key: this.key, | ||
type: this.type, | ||
}; | ||
this.logDetails("type", idObj, values, resolvedValues); | ||
@@ -371,3 +396,3 @@ return this.addConstraint(alias, { values: resolvedValues }); | ||
logDetailed(label, idObj, ...values) { | ||
this.logDetails(label, idObj, ...values) | ||
this.logDetails(label, idObj, ...values); | ||
} | ||
@@ -381,9 +406,14 @@ | ||
notOneOf() { | ||
let values = this.oneOfValues | ||
let values = this.oneOfValues; | ||
if (this.isNothing(values)) return this; | ||
values = this.normalizeValues(values) | ||
const resolvedValues = this.resolveValues(values) | ||
values = this.normalizeValues(values); | ||
const resolvedValues = this.resolveValues(values); | ||
// log details | ||
const idObj = { constraintName: 'notOneOf', method: 'notOneOf', key: this.key, type: this.type} | ||
this.logDetails('type', idObj, values, resolvedValues) | ||
const idObj = { | ||
constraintName: "notOneOf", | ||
method: "notOneOf", | ||
key: this.key, | ||
type: this.type, | ||
}; | ||
this.logDetails("type", idObj, values, resolvedValues); | ||
@@ -394,17 +424,17 @@ return this.addConstraint("notOneOf", { values: resolvedValues }); | ||
resolveValues(values) { | ||
const schemaValues = values | ||
return schemaValues.map(value => { | ||
return this.isObjectType(value) ? this.resolveValue(value) : value | ||
}) | ||
} | ||
const schemaValues = values; | ||
return schemaValues.map((value) => { | ||
return this.isObjectType(value) ? this.resolveValue(value) : value; | ||
}); | ||
} | ||
const() { | ||
let value =this.constraints.const | ||
let value = this.constraints.const; | ||
if (this.isNothing(value)) return this; | ||
// TODO: resolve const data ref if valid format | ||
if (this.isDataRef(value)) { | ||
const dataRefPath = this.normalizeDataRefPath(value) | ||
value = yup.ref(dataRefPath) | ||
} | ||
return this.addConstraint('const', { value }); | ||
const dataRefPath = this.normalizeDataRefPath(value); | ||
value = yup.ref(dataRefPath); | ||
} | ||
return this.addConstraint("const", { value }); | ||
} | ||
@@ -414,14 +444,14 @@ | ||
normalizeDataRefPath(value) { | ||
value = value.$data || value | ||
value = value.$data || value; | ||
// remove first part before / | ||
const parts = value.split('/').shift() | ||
return parts.join('/') | ||
const parts = value.split("/").shift(); | ||
return parts.join("/"); | ||
} | ||
isDataRef(value) { | ||
return this.isPresent(value.$data) | ||
return this.isPresent(value.$data); | ||
} | ||
isConst(value) { | ||
return this.hasKey(value, 'const') | ||
return this.hasKey(value, "const"); | ||
} | ||
@@ -431,14 +461,23 @@ | ||
// special case for const | ||
if (this.isConst(value)) return value['const'] | ||
if (this.isConst(value)) return value["const"]; | ||
const createYupSchemaEntry = this.config.createYupSchemaEntry // || this.entryHandler.createNew | ||
const opts = { schema: this.schema, key: this.key, value, config: this.config } | ||
return createYupSchemaEntry(opts) | ||
const createYupSchemaEntry = this.config.createYupSchemaEntry; // || this.entryHandler.createNew | ||
const opts = { | ||
schema: this.schema, | ||
key: this.key, | ||
value, | ||
config: this.config, | ||
}; | ||
return createYupSchemaEntry(opts); | ||
} | ||
validationErrorMessage(msgName) { | ||
const defaultErrorMessageFn = this.errorMessageHandler.validationErrorMessage.bind(this.errorMessageHandler) | ||
const validationErrorMessageFn = this.config.validationErrorMessage || defaultErrorMessageFn | ||
const defaultErrorMessageFn = | ||
this.errorMessageHandler.validationErrorMessage.bind( | ||
this.errorMessageHandler | ||
); | ||
const validationErrorMessageFn = | ||
this.config.validationErrorMessage || defaultErrorMessageFn; | ||
return validationErrorMessageFn(msgName, this); | ||
} | ||
} | ||
@@ -453,3 +492,3 @@ createWhenConditionFor(when) { | ||
config: this.config, | ||
when | ||
when, | ||
}; | ||
@@ -464,7 +503,7 @@ | ||
label() { | ||
const value = this.value | ||
const label = value.title || value.label | ||
this.base = (label && this.base.label(label)) || this.base | ||
return this | ||
} | ||
const value = this.value; | ||
const label = value.title || value.label; | ||
this.base = (label && this.base.label(label)) || this.base; | ||
return this; | ||
} | ||
@@ -471,0 +510,0 @@ when() { |
@@ -1,5 +0,5 @@ | ||
import { ObjectHandler } from "./handler"; | ||
import { ObjectHandler, createObjectHandler } from "./handler"; | ||
export function toYupObject(obj, config = {}) { | ||
return obj && new ObjectHandler(config).handle(obj); | ||
return obj && createObjectHandler(config).handle(obj); | ||
} | ||
@@ -6,0 +6,0 @@ |
@@ -42,4 +42,7 @@ import { YupMixed } from "../mixed"; | ||
} | ||
const yupSchema = this.config.buildYup(schema, config); | ||
const parentNode = { | ||
key: this.key, | ||
...this.value, | ||
}; | ||
const yupSchema = this.config.buildYup(schema, config, parentNode); | ||
this.base = yupSchema; | ||
@@ -65,3 +68,4 @@ } | ||
$names, | ||
this.validationErrorMessage("propertyNames") || this.validationErrorMessage("noUnknown") | ||
this.validationErrorMessage("propertyNames") || | ||
this.validationErrorMessage("noUnknown") | ||
); | ||
@@ -68,0 +72,0 @@ this.base = newBase || this.base; |
@@ -18,3 +18,2 @@ import { YupMixed } from "../mixed"; | ||
static create(obj) { | ||
@@ -39,3 +38,3 @@ return new YupString(obj); | ||
"url", | ||
"genericFormat" | ||
"genericFormat", | ||
]; | ||
@@ -72,3 +71,3 @@ } | ||
method, | ||
errName: method | ||
errName: method, | ||
}); | ||
@@ -79,3 +78,3 @@ return this; | ||
constraintNameFor(...names) { | ||
return names.find(name => this.constraints[name]); | ||
return names.find((name) => this.constraints[name]); | ||
} | ||
@@ -95,3 +94,3 @@ | ||
method, | ||
errName: method | ||
errName: method, | ||
}); | ||
@@ -108,3 +107,5 @@ return this; | ||
const { minLength } = this.constraints; | ||
const errMsg = this.validationErrorMessage("minLength") || this.validationErrorMessage("min"); | ||
const errMsg = | ||
this.validationErrorMessage("minLength") || | ||
this.validationErrorMessage("min"); | ||
const newBase = minLength && this.base.min(minLength, errMsg); | ||
@@ -118,3 +119,5 @@ this.base = newBase || this.base; | ||
const { maxLength } = this.constraints; | ||
const errMsg = this.validationErrorMessage("maxLength") || this.validationErrorMessage("max"); | ||
const errMsg = | ||
this.validationErrorMessage("maxLength") || | ||
this.validationErrorMessage("max"); | ||
const newBase = maxLength && this.base.max(maxLength, errMsg); | ||
@@ -136,3 +139,5 @@ this.base = newBase || this.base; | ||
const newBase = regex && this.base.matches(regex, {message: errMsg, excludeEmptyString}); | ||
const newBase = | ||
regex && | ||
this.base.matches(regex, { message: errMsg, excludeEmptyString }); | ||
this.base = newBase || this.base; | ||
@@ -139,0 +144,0 @@ return this; |
@@ -9,4 +9,4 @@ import * as yup from "yup"; | ||
export function buildYup(schema, config = {}) { | ||
return new YupBuilder(schema, {...config}).yupSchema; | ||
export function buildYup(schema, config = {}, parentNode) { | ||
return new YupBuilder(schema, { ...config }, parentNode).yupSchema; | ||
} | ||
@@ -19,18 +19,19 @@ | ||
export class YupBuilder extends Base { | ||
constructor(schema, config = {}) { | ||
constructor(schema, config = {}, parentNode) { | ||
super(config); | ||
this.init(schema, config); | ||
this.init(schema, config, parentNode); | ||
} | ||
init(schema, config) { | ||
init(schema, config, parentNode) { | ||
config.buildYup = buildYup; | ||
config.createYupSchemaEntry = | ||
config.createYupSchemaEntry || createYupSchemaEntry; | ||
this.config = Object.assign(this.config, config); | ||
this.config = Object.assign(this.config, config); | ||
this.schema = schema; | ||
const type = this.getType(schema); | ||
const props = this.getProps(schema); | ||
this.parentNode = parentNode; | ||
this.type = type; | ||
this.properties = { | ||
...props | ||
...props, | ||
}; | ||
@@ -40,7 +41,8 @@ this.additionalProps = this.getAdditionalProperties(schema); | ||
this.setLocale() | ||
this.setLocale(); | ||
const customInitFn = typeof config.init === 'function' ? config.init : () => {} | ||
const customInit = customInitFn.bind(this) | ||
customInit(schema, config) | ||
const customInitFn = | ||
typeof config.init === "function" ? config.init : () => {}; | ||
const customInit = customInitFn.bind(this); | ||
customInit(schema, config); | ||
@@ -59,3 +61,5 @@ if (!isObject(type)) { | ||
const name = this.getName(schema); | ||
const buildProperties = (config.buildProperties || this.buildProperties).bind(this) | ||
const buildProperties = ( | ||
config.buildProperties || this.buildProperties | ||
).bind(this); | ||
const properties = buildProperties(schema, this); | ||
@@ -69,3 +73,3 @@ const shapeConfig = this.propsToShape({ properties, name, config }); | ||
get validator() { | ||
return yup | ||
return yup; | ||
} | ||
@@ -104,3 +108,3 @@ | ||
const propKeys = Object.keys(this.properties); | ||
const buildProp = (this.config.buildProp || this.buildProp).bind(this) | ||
const buildProp = (this.config.buildProp || this.buildProp).bind(this); | ||
return propKeys.reduce(buildProp, {}); | ||
@@ -110,3 +114,3 @@ } | ||
getRequiredPropsList() { | ||
return Array.isArray(this.required) ? [...this.required] : [] | ||
return Array.isArray(this.required) ? [...this.required] : []; | ||
} | ||
@@ -116,9 +120,13 @@ | ||
const value = this.properties[key]; | ||
const required = this.getRequiredPropsList(); | ||
const setRequired = (this.config.setRequired || this.setRequired).bind(this) | ||
const required = this.getRequiredPropsList(); | ||
const setRequired = (this.config.setRequired || this.setRequired).bind( | ||
this | ||
); | ||
// normalize required for prop | ||
setRequired(value, key, required) | ||
setRequired(value, key, required); | ||
// set schema property entry | ||
const setPropEntry = (this.config.setPropEntry || this.setPropEntry).bind(this) | ||
setPropEntry(propObj, key, value) | ||
const setPropEntry = (this.config.setPropEntry || this.setPropEntry).bind( | ||
this | ||
); | ||
setPropEntry(propObj, key, value); | ||
return propObj; | ||
@@ -128,3 +136,3 @@ } | ||
// normalize required for prop | ||
setRequired(value, key, required) { | ||
setRequired(value, key, required) { | ||
const isRequired = required.indexOf(key) >= 0; | ||
@@ -135,3 +143,3 @@ if (!isObjectType(value)) { | ||
value.required = this.isRequired(value) || isRequired; | ||
return value | ||
return value; | ||
} | ||
@@ -144,3 +152,3 @@ | ||
...value, | ||
} | ||
}; | ||
} | ||
@@ -165,3 +173,3 @@ | ||
const properties = { | ||
...this.properties | ||
...this.properties, | ||
}; | ||
@@ -171,9 +179,12 @@ const keys = Object.keys(properties); | ||
const value = properties[key]; | ||
const yupSchemaEntry = this.propToYupSchemaEntry({ | ||
const argsObj = { | ||
name, | ||
key, | ||
value | ||
}); | ||
this.logInfo("propsToShape", { key, yupSchemaEntry }); | ||
acc[key] = yupSchemaEntry; | ||
value, | ||
}; | ||
const yupSchemaEntry = this.propToYupSchemaEntry(argsObj); | ||
this.logInfo("propsToShape", { ...argsObj, yupSchemaEntry }); | ||
if (yupSchemaEntry) { | ||
acc[key] = yupSchemaEntry; | ||
} | ||
return acc; | ||
@@ -184,4 +195,5 @@ }, {}); | ||
propToYupSchemaEntry({ name, key, value = {} }) { | ||
return this.createYupSchemaEntry({ | ||
const schemaEntryObj = { | ||
schema: this.schema, | ||
parentNode: this.parentNode || this, | ||
name, | ||
@@ -191,4 +203,5 @@ key, | ||
config: this.config, | ||
builder: this | ||
}); | ||
builder: this, | ||
}; | ||
return this.createYupSchemaEntry(schemaEntryObj); | ||
} | ||
@@ -201,4 +214,4 @@ | ||
onConstraintAdded(constraint) { | ||
this.logInfo('Constraint Added', constraint) | ||
this.logInfo("Constraint Added", constraint); | ||
} | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
329059
3680
1786