@sot1986/appsync-precognition 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{baseErrors,cleanString,date,datetime,email,getHeader,getNestedValue,integer,isArray,isParentPathValid,numeric,parseErrorMessage,phone,setNestedValue,time,ulid,url,uuid}from"./utils.js";import{runtime,util}from"@aws-appsync/utils";const regexRules={email,phone,url,uuid,ulid,integer,date,time,datetime,numeric};function parse(opt,rule){const[n,...p]=typeof rule===`string`?[rule,void 0]:isArray(rule)?[rule[0],...rule.slice(1)]:typeof rule.rule===`string`?[rule.rule,void 0]:[rule.rule[0],...rule.rule.slice(1)];switch(n){case`required`:return requiredRule(opt);case`nullable`:return nullableRule(opt);case`sometimes`:util.error(`sometimes rule is not allowed here`);break;case`min`:case`bigger`:return betweenRule(opt,p[0],void 0,n===`bigger`);case`max`:case`lower`:return betweenRule(opt,void 0,p[0],n===`lower`);case`between`:case`within`:return betweenRule(opt,p[0],p[1],n===`within`);case`regex`:return regexRule(opt,...p);case`in`:return inRule(opt,...p);case`notIn`:return notInRule(opt,...p);case`before`:case`beforeOrEqual`:return beforeRule(opt,p[0],n===`before`);case`after`:case`afterOrEqual`:return afterRule(opt,p[0],n===`after`);case`email`:case`phone`:case`url`:case`uuid`:case`ulid`:case`integer`:case`date`:case`time`:case`datetime`:case`numeric`:return regexRule({...opt,msg:opt.msg??opt.errors[n]},regexRules[n]);case`unique`:return uniqueRule(opt);default:return typeRule(opt,n)}}function betweenRule({value,msg,errors},minV=-Infinity,maxV=Infinity,strict=false){const[min,max]=[maxV===Infinity,minV===-Infinity];const result={check:false,msg:msg??min?strict?errors.biggerNumber:errors.minNumber:max?strict?errors.lowerNumber:errors.maxNumber:strict?errors.withinNumber:errors.betweenNumber,value,params:{":min":`${minV}`,":max":`${maxV}`}};if(typeof value===`number`)result.check=strict?value>minV&&value<maxV:value>=minV&&value<=maxV;if(typeof value===`string`){result.check=value.length>=minV&&value.length<=maxV;result.msg=msg??min?errors.minString:max?errors.maxString:errors.betweenString}if(isArray(value)){result.check=value.length>=minV&&value.length<=maxV;result.msg=msg??min?errors.minArray:max?errors.maxArray:errors.betweenArray}return result}function regexRule(opt,...pat){const res={check:false,msg:opt.msg??opt.errors.regex,value:opt.value};if(typeof opt.value===`string`||typeof opt.value===`number`){const valStr=typeof opt.value===`string`?opt.value:`${opt.value}`;pat.forEach(p=>{res.check=res.check||util.matches(p,valStr)})}return res}function inRule({value,msg,errors},...p){return{check:p.includes(value),msg:msg??errors.in,value,params:{":in":p.join(`, `)}}}function notInRule({value,msg,errors},...p){return{check:!p.includes(value),msg:msg??errors.notIn,value,params:{":notIn":p.join(`, `)}}}function requiredRule({value,msg,errors}){const result={check:true,msg:msg??errors.required,value,skipNext:true};if(typeof value===`string`)result.check=value.length>0;if(isArray(value))result.check=value.length>0;if(typeof value===`number`)result.check=true;if(typeof value===`boolean`)result.check=true;if(typeof value===`object`&&!result.value)result.check=false;if(typeof value===`undefined`)result.check=false;result.skipNext=!result.check;return result}function nullableRule({value,msg,errors}){return{check:true,msg:msg??errors.nullable,value,skipNext:typeof value===`undefined`||value===null}}function sometimesRule({value,msg,errors,parent,key}){const result={check:true,msg:msg??errors.sometimes,value};if(!Object.hasOwn(parent,key)){result.skipNext=true;return result}if(typeof value===`object`&&!result.value){result.check=false;result.skipNext=true;return result}return requiredRule({value,msg,errors})}function typeRule({value,msg,errors},type){const result={check:false,msg:msg??errors.type,value,params:{":type":type}};switch(type){case`array`:result.check=isArray(value);break;case`object`:result.check=typeof value===`object`&&!!value&&!isArray(value)&&Object.keys(value).length>0;break;case`boolean`:result.check=typeof value===`boolean`;break;case`number`:result.check=typeof value===`number`;break;default:result.check=typeof value===`string`}return result}function beforeRule({value,msg,errors},start,strict=false){const result={check:false,msg:msg??errors.before,value,params:strict?{":before":start}:{":beforeOrEqual":start}};const startValue=util.time.parseISO8601ToEpochMilliSeconds(start);const numDate=typeof value===`string`?util.time.parseISO8601ToEpochMilliSeconds(value):value;if(typeof numDate===`number`)result.check=strict?numDate<startValue:numDate<=startValue;return result}function afterRule({value,msg,errors},p,strict=false){const result={check:false,msg:msg??strict?errors.after:errors.afterOrEqual,value,params:strict?{":after":p}:{":afterOrEqual":p}};const e=util.time.parseISO8601ToEpochMilliSeconds(p);const numDate=typeof value===`string`?util.time.parseISO8601ToEpochMilliSeconds(value):value;if(typeof numDate===`number`)result.check=strict?numDate>e:numDate>=e;return result}function uniqueRule({value,msg,errors}){const result={check:false,msg:msg??errors.unique,value};if(isArray(value)){const occurrences={};value.forEach(item=>{const key=typeof item===`string`?item:`${item}`;occurrences[key]=(occurrences[key]||0)+1});result.check=Object.values(occurrences).every(count=>count===1)}return result}function isRule(rule){return typeof rule===`object`&&!!rule&&Object.hasOwn(rule,`check`)}function isCustomFullRule(rule){return typeof rule===`object`&&!!rule&&Object.hasOwn(rule,`rule`)}function validate(obj,checks,options){let error={};const errors={...baseErrors,...options?.errors};if(typeof obj!==`object`||!obj)util.error(`Object expected`);sanitizeNestedArray(obj,checks);if(options?.attributes)sanitizeNestedArray(obj,options.attributes);const validated=JSON.parse(JSON.stringify(obj));Object.keys(checks).forEach(path=>{if(path.split(`.`).length>1){if(!isParentPathValid(validated,path.split(`.`).slice(0,-1).join(`.`)))return}let value=getNestedValue(validated,path);const parent=path.split(`.`).length>1?getNestedValue(validated,path.split(`.`).slice(0,-1).join(`.`)):validated;if(typeof value===`string`){value=cleanString(value,options);setNestedValue(validated,path,value)}let skip=false;const keyRules=checks[path];if(keyRules?.length)keyRules.forEach(rule=>{if(skip)return;const result=isRule(rule)?{...rule,value,msg:rule.msg??errors.invalid}:isCustomFullRule(rule)?parse({value,msg:rule.msg,errors},rule.rule):rule===`sometimes`?sometimesRule({value,errors,parent,key:path.split(`.`).pop()}):parse({value,errors},rule);skip=!!result.skipNext||!result.check;if(result.check)return;if(error.msg)appendValidationError(error.msg,{...error.errorInfo});result.params=result.params??{};if(util.matches(`:attr`,result.msg))result.params[`:attr`]=options?.attributes?.[`:${path}`]??formatAttributeName(path);error={msg:parseErrorMessage(result.msg,result.params),errorType:`ValidationError`,data:null,errorInfo:{path,value}}})});if(!error.msg)return validated;validationError(error.msg,{...error.errorInfo})}function sanitizeNestedArray(obj,nested){let maxKeys=[];Object.keys(nested).forEach(path=>{const currentKeys=path.split(`.`).filter(k=>k===`*`);if(currentKeys.length>maxKeys.length)maxKeys=[...currentKeys]});maxKeys.forEach(()=>{Object.keys(nested).forEach(path=>{const keys=path.split(`.`);const wildcardIdx=keys.indexOf(`*`,1);if(wildcardIdx<1)return;const parentPath=keys.slice(0,wildcardIdx).join(`.`);const cleanParentPath=parentPath.startsWith(`:`)?parentPath.slice(1):parentPath;if(!isParentPathValid(obj,cleanParentPath)){delete nested[path];return}const parentValue=getNestedValue(obj,cleanParentPath);if(!isArray(parentValue)){delete nested[path];return}parentValue.forEach((_,i)=>{const idxPath=[...keys];idxPath[wildcardIdx]=`${i}`;nested[idxPath.join(`.`)]=nested[path]});delete nested[path]})})}function precognitiveValidation(ctx,checks,options){const{errors,attributes}=isLocalized(ctx)?{errors:{...ctx.stash.__i18n.errors,...options?.errors},attributes:{...ctx.stash.__i18n.attributes,...options?.attributes}}:{errors:options?.errors,attributes:options?.attributes};if(getHeader(`precognition`,ctx)!==`true`)return ctx.stash.__validated=validate(ctx.args,checks,{...options,errors,attributes});const validationKeys=getHeader(`Precognition-Validate-Only`,ctx)?.split(`,`).map(key=>key.trim());util.http.addResponseHeader(`Precognition`,`true`);if(!validationKeys){ctx.stash.__validated=validate(ctx.args,checks,{...options,errors,attributes});util.http.addResponseHeader(`Precognition-Success`,`true`);runtime.earlyReturn(null)}util.http.addResponseHeader(`Precognition-Validate-Only`,validationKeys.join(`,`));const precognitionChecks={};validationKeys.forEach(key=>{precognitionChecks[key]=checks[key]});ctx.stash.__validated=validate(ctx.args,precognitionChecks,{...options,errors,attributes});util.http.addResponseHeader(`Precognition-Success`,`true`);runtime.earlyReturn(null,{skipTo:options?.skipTo??`END`})}function validationError(msg,options){util.error(msg,`ValidationError`,null,{...options})}function appendValidationError(msg,options){util.appendError(msg,`ValidationError`,null,{...options})}function formatAttributeName(path){return path.split(`.`).reduce((acc,part)=>{if(util.matches(`^\\d+$`,part))return acc;let words=``;part.split(``).forEach((char,idx)=>{if(idx!==0&&util.matches(`[A-Z]`,char))words+=` `;words+=char.toLowerCase()});return acc?`${acc} ${words}`:words},``)}function assertValidated(ctx){if(Object.hasOwn(ctx.stash,`__validated`))return;util.error(`Context arguments have not been validated`)}function isLocalized(ctx,locale){if(Object.hasOwn(ctx.stash,`__i18n`)&&typeof ctx.stash?.__i18n.locale===`string`)return locale?ctx.stash.__i18n.locale===locale:true;return false}function assertLocalized(ctx,locale){if(isLocalized(ctx,locale))return;util.error(`Context arguements have not been localized`)}export{appendValidationError,assertLocalized,assertValidated,formatAttributeName,isLocalized,precognitiveValidation,validate,validationError};
|
|
1
|
+
import{baseErrors,cleanString,date,datetime,email,getHeader,getNestedValue,integer,isArray,isParentPathValid,numeric,parseErrorMessage,phone,setNestedValue,time,ulid,url,uuid}from"./utils.js";import{runtime,util}from"@aws-appsync/utils";const regexRules={email,phone,url,uuid,ulid,integer,date,time,datetime,numeric};function parse(opt,rule){const[n,...p]=typeof rule===`string`?[rule,void 0]:isArray(rule)?[rule[0],...rule.slice(1)]:typeof rule.rule===`string`?[rule.rule,void 0]:[rule.rule[0],...rule.rule.slice(1)];switch(n){case`required`:return requiredRule(opt);case`nullable`:return nullableRule(opt);case`sometimes`:util.error(`sometimes rule is not allowed here`);break;case`min`:case`bigger`:return betweenRule(opt,p[0],void 0,n===`bigger`);case`max`:case`lower`:return betweenRule(opt,void 0,p[0],n===`lower`);case`between`:case`within`:return betweenRule(opt,p[0],p[1],n===`within`);case`regex`:return regexRule(opt,...p);case`in`:return inRule(opt,...p);case`notIn`:return notInRule(opt,...p);case`before`:case`beforeOrEqual`:return beforeRule(opt,p[0],n===`before`);case`after`:case`afterOrEqual`:return afterRule(opt,p[0],n===`after`);case`email`:case`phone`:case`url`:case`uuid`:case`ulid`:case`integer`:case`date`:case`time`:case`datetime`:case`numeric`:return regexRule({...opt,msg:opt.msg??opt.errors[n]},regexRules[n]);case`unique`:return uniqueRule(opt);default:return typeRule(opt,n)}}function betweenRule({value,msg,errors},minV=-Infinity,maxV=Infinity,strict=false){const[min,max]=[maxV===Infinity,minV===-Infinity];const result={check:false,msg:msg??min?strict?errors.biggerNumber:errors.minNumber:max?strict?errors.lowerNumber:errors.maxNumber:strict?errors.withinNumber:errors.betweenNumber,value,params:{":min":`${minV}`,":max":`${maxV}`}};if(typeof value===`number`)result.check=strict?value>minV&&value<maxV:value>=minV&&value<=maxV;if(typeof value===`string`){result.check=value.length>=minV&&value.length<=maxV;result.msg=msg??min?errors.minString:max?errors.maxString:errors.betweenString}if(isArray(value)){result.check=value.length>=minV&&value.length<=maxV;result.msg=msg??min?errors.minArray:max?errors.maxArray:errors.betweenArray}return result}function regexRule(opt,...pat){const res={check:false,msg:opt.msg??opt.errors.regex,value:opt.value};if(typeof opt.value===`string`||typeof opt.value===`number`){const valStr=typeof opt.value===`string`?opt.value:`${opt.value}`;pat.forEach(p=>{res.check=res.check||util.matches(p,valStr)})}return res}function inRule({value,msg,errors},...p){return{check:p.includes(value),msg:msg??errors.in,value,params:{":in":p.join(`, `)}}}function notInRule({value,msg,errors},...p){return{check:!p.includes(value),msg:msg??errors.notIn,value,params:{":notIn":p.join(`, `)}}}function requiredRule({value,msg,errors}){const result={check:true,msg:msg??errors.required,value,skipNext:true};if(typeof value===`string`)result.check=value.length>0;if(isArray(value))result.check=value.length>0;if(typeof value===`number`)result.check=true;if(typeof value===`boolean`)result.check=true;if(typeof value===`object`&&!result.value)result.check=false;if(typeof value===`undefined`)result.check=false;result.skipNext=!result.check;return result}function nullableRule({value,msg,errors}){return{check:true,msg:msg??errors.nullable,value,skipNext:typeof value===`undefined`||value===null}}function sometimesRule({value,msg,errors,parent,key}){const result={check:true,msg:msg??errors.sometimes,value};if(!Object.hasOwn(parent,key)){result.skipNext=true;return result}if(typeof value===`object`&&!result.value){result.check=false;result.skipNext=true;return result}return requiredRule({value,msg,errors})}function typeRule({value,msg,errors},type){const result={check:false,msg:msg??errors.type,value,params:{":type":type}};switch(type){case`array`:result.check=isArray(value);break;case`object`:result.check=typeof value===`object`&&!!value&&!isArray(value)&&Object.keys(value).length>0;break;case`boolean`:result.check=typeof value===`boolean`;break;case`number`:result.check=typeof value===`number`;break;default:result.check=typeof value===`string`}return result}function beforeRule({value,msg,errors},start,strict=false){const result={check:false,msg:msg??errors.before,value,params:strict?{":before":start}:{":beforeOrEqual":start}};const compareValue=typeof value===`number`?util.time.epochMilliSecondsToISO8601(value>1e10?value:value*1e3):value;if(typeof compareValue!==`string`)return result;result.check=strict?compareValue<start:compareValue<=start;return result}function afterRule({value,msg,errors},p,strict=false){const result={check:false,msg:msg??strict?errors.after:errors.afterOrEqual,value,params:strict?{":after":p}:{":afterOrEqual":p}};const compareValue=typeof value===`number`?util.time.epochMilliSecondsToISO8601(value>1e10?value:value*1e3):value;if(typeof compareValue!==`string`)return result;result.check=strict?compareValue>p:compareValue>=p;return result}function uniqueRule({value,msg,errors}){const result={check:false,msg:msg??errors.unique,value};if(isArray(value)){const occurrences={};value.forEach(item=>{const key=typeof item===`string`?item:`${item}`;occurrences[key]=(occurrences[key]||0)+1});result.check=Object.values(occurrences).every(count=>count===1)}return result}function isRule(rule){return typeof rule===`object`&&!!rule&&Object.hasOwn(rule,`check`)}function isCustomFullRule(rule){return typeof rule===`object`&&!!rule&&Object.hasOwn(rule,`rule`)}function validate(obj,checks,options){let error={};const errors={...baseErrors,...options?.errors};if(typeof obj!==`object`||!obj)util.error(`Object expected`);sanitizeNestedArray(obj,checks);if(options?.attributes)sanitizeNestedArray(obj,options.attributes);const validated=JSON.parse(JSON.stringify(obj));Object.keys(checks).forEach(path=>{if(path.split(`.`).length>1){if(!isParentPathValid(validated,path.split(`.`).slice(0,-1).join(`.`)))return}let value=getNestedValue(validated,path);const parent=path.split(`.`).length>1?getNestedValue(validated,path.split(`.`).slice(0,-1).join(`.`)):validated;if(typeof value===`string`){value=cleanString(value,options);setNestedValue(validated,path,value)}let skip=false;const keyRules=checks[path];if(keyRules?.length)keyRules.forEach(rule=>{if(skip)return;const result=isRule(rule)?{...rule,value,msg:rule.msg??errors.invalid}:isCustomFullRule(rule)?parse({value,msg:rule.msg,errors},rule.rule):rule===`sometimes`?sometimesRule({value,errors,parent,key:path.split(`.`).pop()}):parse({value,errors},rule);skip=!!result.skipNext||!result.check;if(result.check)return;if(error.msg)appendValidationError(error.msg,{...error.errorInfo});result.params=result.params??{};if(util.matches(`:attr`,result.msg))result.params[`:attr`]=options?.attributes?.[`:${path}`]??formatAttributeName(path);error={msg:parseErrorMessage(result.msg,result.params),errorType:`ValidationError`,data:null,errorInfo:{path,value}}})});if(!error.msg)return validated;validationError(error.msg,{...error.errorInfo})}function sanitizeNestedArray(obj,nested){let maxKeys=[];Object.keys(nested).forEach(path=>{const currentKeys=path.split(`.`).filter(k=>k===`*`);if(currentKeys.length>maxKeys.length)maxKeys=[...currentKeys]});maxKeys.forEach(()=>{Object.keys(nested).forEach(path=>{const keys=path.split(`.`);const wildcardIdx=keys.indexOf(`*`,1);if(wildcardIdx<1)return;const parentPath=keys.slice(0,wildcardIdx).join(`.`);const cleanParentPath=parentPath.startsWith(`:`)?parentPath.slice(1):parentPath;if(!isParentPathValid(obj,cleanParentPath)){delete nested[path];return}const parentValue=getNestedValue(obj,cleanParentPath);if(!isArray(parentValue)){delete nested[path];return}parentValue.forEach((_,i)=>{const idxPath=[...keys];idxPath[wildcardIdx]=`${i}`;nested[idxPath.join(`.`)]=nested[path]});delete nested[path]})})}function precognitiveValidation(ctx,checks,options){const{errors,attributes}=isLocalized(ctx)?{errors:{...ctx.stash.__i18n.errors,...options?.errors},attributes:{...ctx.stash.__i18n.attributes,...options?.attributes}}:{errors:options?.errors,attributes:options?.attributes};if(getHeader(`precognition`,ctx)!==`true`)return ctx.stash.__validated=validate(ctx.args,checks,{...options,errors,attributes});const validationKeys=getHeader(`Precognition-Validate-Only`,ctx)?.split(`,`).map(key=>key.trim());util.http.addResponseHeader(`Precognition`,`true`);if(!validationKeys){ctx.stash.__validated=validate(ctx.args,checks,{...options,errors,attributes});util.http.addResponseHeader(`Precognition-Success`,`true`);runtime.earlyReturn(null)}util.http.addResponseHeader(`Precognition-Validate-Only`,validationKeys.join(`,`));const precognitionChecks={};validationKeys.forEach(key=>{precognitionChecks[key]=checks[key]});ctx.stash.__validated=validate(ctx.args,precognitionChecks,{...options,errors,attributes});util.http.addResponseHeader(`Precognition-Success`,`true`);runtime.earlyReturn(null,{skipTo:options?.skipTo??`END`})}function validationError(msg,options){util.error(msg,`ValidationError`,null,{...options})}function appendValidationError(msg,options){util.appendError(msg,`ValidationError`,null,{...options})}function formatAttributeName(path){return path.split(`.`).reduce((acc,part)=>{if(util.matches(`^\\d+$`,part))return acc;let words=``;part.split(``).forEach((char,idx)=>{if(idx!==0&&util.matches(`[A-Z]`,char))words+=` `;words+=char.toLowerCase()});return acc?`${acc} ${words}`:words},``)}function assertValidated(ctx){if(Object.hasOwn(ctx.stash,`__validated`))return;util.error(`Context arguments have not been validated`)}function isLocalized(ctx,locale){if(Object.hasOwn(ctx.stash,`__i18n`)&&typeof ctx.stash?.__i18n.locale===`string`)return locale?ctx.stash.__i18n.locale===locale:true;return false}function assertLocalized(ctx,locale){if(isLocalized(ctx,locale))return;util.error(`Context arguements have not been localized`)}export{appendValidationError,assertLocalized,assertValidated,formatAttributeName,isLocalized,precognitiveValidation,validate,validationError};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["rules.parse","rules.sometimesRule"],"sources":["../src/rules.ts","../src/index.ts"],"sourcesContent":["import type { CustomFullRule, FullRule, ParsedRule, ParseOptions } from './types'\nimport { util } from '@aws-appsync/utils'\nimport { date, datetime, email, integer, isArray, numeric, phone, time, ulid, url, uuid } from './utils'\n\nconst regexRules = {\n email,\n phone,\n url,\n uuid,\n ulid,\n integer,\n date,\n time,\n datetime,\n numeric,\n} as const\n\nexport function parse<T>(\n opt: ParseOptions<T>,\n rule: FullRule | CustomFullRule,\n): ParsedRule<T> {\n const [n, ...p] = typeof rule === 'string'\n ? [rule, undefined]\n : isArray(rule)\n ? [rule[0], ...rule.slice(1)]\n : typeof rule.rule === 'string'\n ? [rule.rule, undefined]\n : [rule.rule[0], ...rule.rule.slice(1)]\n\n switch (n) {\n case 'required':\n return requiredRule(opt)\n case 'nullable':\n return nullableRule(opt)\n case 'sometimes':\n util.error('sometimes rule is not allowed here')\n break\n case 'min':\n case 'bigger':\n return betweenRule(opt, (p[0]! as number), undefined, n === 'bigger')\n case 'max':\n case 'lower':\n return betweenRule(opt, undefined, (p[0] as number), n === 'lower')\n case 'between':\n case 'within':\n return betweenRule(opt, (p[0] as number), p[1] as number, n === 'within')\n case 'regex':\n return regexRule(opt, ...p as string[])\n case 'in':\n return inRule(opt, ...p)\n case 'notIn':\n return notInRule(opt, ...p)\n case 'before':\n case 'beforeOrEqual':\n return beforeRule(opt, p[0] as string, n === 'before')\n case 'after':\n case 'afterOrEqual':\n return afterRule(opt, p[0] as string, n === 'after')\n case 'email':\n case 'phone':\n case 'url':\n case 'uuid':\n case 'ulid':\n case 'integer':\n case 'date':\n case 'time':\n case 'datetime':\n case 'numeric':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors[n] }, regexRules[n])\n case 'unique':\n return uniqueRule(opt)\n default:\n return typeRule(opt, n)\n }\n}\n\nfunction betweenRule<T>(\n { value, msg, errors }: ParseOptions<T>,\n minV: number = -Infinity,\n maxV: number = Infinity,\n strict = false,\n): ParsedRule<T> {\n const [min, max] = [maxV === Infinity, minV === -Infinity]\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? min\n ? strict\n ? errors.biggerNumber\n : errors.minNumber\n : max\n ? strict\n ? errors.lowerNumber\n : errors.maxNumber\n : strict\n ? errors.withinNumber\n : errors.betweenNumber,\n value,\n params: {\n ':min': `${minV}`,\n ':max': `${maxV}`,\n },\n }\n if (typeof value === 'number')\n result.check = strict ? value > minV && value < maxV : value >= minV && value <= maxV\n\n if (typeof value === 'string') {\n result.check = value.length >= minV && value.length <= maxV\n result.msg = msg ?? min\n ? errors.minString\n : max\n ? errors.maxString\n : errors.betweenString\n }\n if (isArray(value)) {\n result.check = value.length >= minV && value.length <= maxV\n result.msg = msg ?? min\n ? errors.minArray\n : max\n ? errors.maxArray\n : errors.betweenArray\n }\n return result\n}\n\nfunction regexRule<T>(opt: ParseOptions<T>, ...pat: string[]): ParsedRule<T> {\n const res: ParsedRule<T> = {\n check: false,\n msg: opt.msg ?? opt.errors.regex,\n value: opt.value,\n }\n if (typeof opt.value === 'string' || typeof opt.value === 'number') {\n const valStr = typeof opt.value === 'string' ? opt.value : `${opt.value}`\n pat.forEach((p) => {\n res.check = res.check || util.matches(p, valStr)\n })\n }\n return res\n}\n\nfunction inRule<T>({ value, msg, errors }: ParseOptions<T>, ...p: unknown[]): ParsedRule<T> {\n return {\n check: p.includes(value),\n msg: msg ?? errors.in,\n value,\n params: { ':in': p.join(', ') },\n }\n}\n\nfunction notInRule<T>({ value, msg, errors }: ParseOptions<T>, ...p: unknown[]): ParsedRule<T> {\n return {\n check: !p.includes(value),\n msg: msg ?? errors.notIn,\n value,\n params: { ':notIn': p.join(', ') },\n }\n}\n\nexport function requiredRule<T>({ value, msg, errors }: ParseOptions<T>): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: true,\n msg: msg ?? errors.required,\n value,\n skipNext: true,\n }\n if (typeof value === 'string')\n result.check = value.length > 0\n if (isArray(value))\n result.check = value.length > 0\n if (typeof value === 'number')\n result.check = true\n if (typeof value === 'boolean')\n result.check = true\n if (typeof value === 'object' && !result.value) {\n result.check = false\n }\n if (typeof value === 'undefined')\n result.check = false\n result.skipNext = !result.check\n return result\n}\n\nfunction nullableRule<T>({ value, msg, errors }: ParseOptions<T>): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: true,\n msg: msg ?? errors.nullable,\n value,\n skipNext: typeof value === 'undefined' || value === null,\n }\n return result\n}\n\nexport function sometimesRule<T>({ value, msg, errors, parent, key }: ParseOptions<T> & { parent: object, key: string }): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: true,\n msg: msg ?? errors.sometimes,\n value,\n }\n if (!Object.hasOwn(parent, key)) {\n result.skipNext = true\n return result\n }\n if (typeof value === 'object' && !result.value) {\n result.check = false\n result.skipNext = true\n return result\n }\n return requiredRule({ value, msg, errors })\n}\n\nfunction typeRule<T>({ value, msg, errors }: ParseOptions<T>, type: 'boolean' | 'object' | 'array' | 'number' | 'string'): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? errors.type,\n value,\n params: { ':type': type },\n }\n switch (type) {\n case 'array':\n result.check = isArray(value)\n break\n case 'object':\n result.check = typeof value === 'object' && !!value && !isArray(value) && Object.keys(value).length > 0\n break\n case 'boolean':\n result.check = typeof value === 'boolean'\n break\n case 'number':\n result.check = typeof value === 'number'\n break\n default:\n result.check = typeof value === 'string'\n }\n return result\n}\n\nfunction beforeRule<T>({ value, msg, errors }: ParseOptions<T>, start: string, strict = false): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? errors.before,\n value,\n params: strict\n ? { ':before': start }\n : { ':beforeOrEqual': start },\n }\n const startValue = util.time.parseISO8601ToEpochMilliSeconds(start)\n const numDate = typeof value === 'string'\n ? util.time.parseISO8601ToEpochMilliSeconds(value)\n : value\n if (typeof numDate === 'number')\n result.check = strict ? numDate < startValue : numDate <= startValue\n return result\n}\n\nfunction afterRule<T>({ value, msg, errors }: ParseOptions<T>, p: string, strict = false): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? strict ? errors.after : errors.afterOrEqual,\n value,\n params: strict\n ? { ':after': p }\n : { ':afterOrEqual': p },\n }\n const e = util.time.parseISO8601ToEpochMilliSeconds(p)\n const numDate = typeof value === 'string'\n ? util.time.parseISO8601ToEpochMilliSeconds(value)\n : value\n if (typeof numDate === 'number')\n result.check = strict ? numDate > e : numDate >= e\n\n return result\n}\n\nfunction uniqueRule<T>({ value, msg, errors }: ParseOptions<T>): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? errors.unique,\n value,\n }\n if (isArray(value)) {\n const occurrences: Record<string, number> = {}\n value.forEach((item) => {\n const key = typeof item === 'string' ? item : `${item}`\n occurrences[key] = (occurrences[key] || 0) + 1\n })\n result.check = Object.values(occurrences).every(count => count === 1)\n }\n return result\n}\n","import type { Ctx, CustomFullRule, FullRule, I18n, NestedKeyOf, Rule, ValidationErrors } from './types'\nimport { runtime, util } from '@aws-appsync/utils'\nimport * as rules from './rules'\nimport { baseErrors, cleanString, getHeader, getNestedValue, isArray, isParentPathValid, parseErrorMessage, setNestedValue } from './utils'\n\nfunction isRule(rule: FullRule | CustomFullRule | Omit<Rule, 'value'>): rule is Omit<Rule, 'value'> {\n return typeof rule === 'object' && !!rule && Object.hasOwn(rule, 'check')\n}\n\nfunction isCustomFullRule(rule: FullRule | CustomFullRule | Omit<Rule, 'value'>): rule is CustomFullRule {\n return typeof rule === 'object' && !!rule && Object.hasOwn(rule, 'rule')\n}\n\nexport function validate<T>(\n obj: Readonly<Partial<T>>,\n checks: Partial<{\n [key in NestedKeyOf<T>]: Array<\n | FullRule\n | CustomFullRule\n | Omit<Rule<T>, 'value'>\n > }>,\n options?: {\n trim?: boolean\n allowEmptyString?: boolean\n errors?: Partial<ValidationErrors>\n attributes?: Partial<Record<`:${NestedKeyOf<T>}`, string>>\n },\n): T {\n let error: { msg?: string, errorType?: string, data?: any, errorInfo?: any } = {}\n const errors: ValidationErrors = { ...baseErrors, ...options?.errors }\n if (typeof obj !== 'object' || !obj)\n util.error('Object expected')\n\n sanitizeNestedArray(obj, checks)\n if (options?.attributes)\n sanitizeNestedArray(obj, options.attributes)\n\n const validated: T & object = JSON.parse(JSON.stringify(obj))\n Object.keys(checks).forEach((path) => {\n if (path.split('.').length > 1) {\n const parentPath = path.split('.').slice(0, -1).join('.')\n if (!isParentPathValid(validated, parentPath))\n return\n }\n\n let value = getNestedValue(validated, path)\n const parent: object = path.split('.').length > 1\n ? getNestedValue(validated, path.split('.').slice(0, -1).join('.'))\n : validated\n if (typeof value === 'string') {\n value = cleanString(value, options)\n setNestedValue(validated, path as NestedKeyOf<T>, value)\n }\n\n let skip: boolean = false\n const keyRules = checks[path as keyof typeof checks]\n if (keyRules?.length) {\n keyRules.forEach((rule) => {\n if (skip)\n return\n\n const result = isRule(rule)\n ? { ...rule, value, msg: rule.msg ?? errors.invalid }\n : isCustomFullRule(rule)\n ? rules.parse({ value, msg: rule.msg, errors }, rule.rule)\n : rule === 'sometimes'\n ? rules.sometimesRule({ value, errors, parent, key: path.split('.').pop()! })\n : rules.parse({ value, errors }, rule)\n\n skip = !!result.skipNext || !result.check\n\n if (result.check)\n return\n\n if (error.msg)\n appendValidationError(error.msg, { ...error.errorInfo })\n\n result.params = result.params ?? {}\n\n if (util.matches(':attr', result.msg))\n result.params[':attr'] = options?.attributes?.[`:${path as NestedKeyOf<T>}`] ?? formatAttributeName(path as NestedKeyOf<T>)\n\n error = {\n msg: parseErrorMessage(result.msg, result.params),\n errorType: 'ValidationError',\n data: null,\n errorInfo: { path, value },\n }\n })\n }\n })\n\n if (!error.msg) {\n return validated as T\n }\n\n validationError(error.msg, { ...error.errorInfo })\n}\n\nfunction sanitizeNestedArray(\n obj: object,\n nested: object,\n): void {\n let maxKeys: string[] = []\n Object.keys(nested).forEach((path: string) => {\n const currentKeys = path.split('.').filter(k => k === '*')\n if (currentKeys.length > maxKeys.length) {\n maxKeys = [...currentKeys]\n }\n })\n\n maxKeys.forEach(() => {\n Object.keys(nested).forEach((path) => {\n const keys = path.split('.')\n const wildcardIdx = keys.indexOf('*', 1)\n\n if (wildcardIdx < 1)\n return\n\n const parentPath = keys.slice(0, wildcardIdx).join('.')\n const cleanParentPath = parentPath.startsWith(':') ? parentPath.slice(1) : parentPath\n\n if (!isParentPathValid(obj, cleanParentPath)) {\n delete nested[path as keyof typeof nested]\n return\n }\n\n const parentValue = getNestedValue(obj, cleanParentPath)\n\n if (!isArray(parentValue)) {\n delete nested[path as keyof typeof nested]\n return\n }\n\n parentValue.forEach((_, i) => {\n const idxPath = [...keys]\n idxPath[wildcardIdx] = `${i}`\n nested[idxPath.join('.') as keyof typeof nested] = nested[path as keyof typeof nested]\n })\n delete nested[path as keyof typeof nested]\n })\n })\n}\n\nexport function precognitiveValidation<T>(\n ctx: Ctx<Partial<T>>,\n checks: Partial<{\n [key in NestedKeyOf<T>]: Array<\n | FullRule\n | CustomFullRule\n | Omit<Rule, 'value'>\n > }>,\n options?: {\n trim?: boolean\n allowEmptyString?: boolean\n skipTo?: 'END' | 'NEXT'\n errors?: Partial<ValidationErrors>\n attributes?: Partial<Record<`:${NestedKeyOf<T>}`, string>>\n },\n): T {\n const { errors, attributes } = (isLocalized<T, string>(ctx)\n ? {\n errors: {\n ...ctx.stash.__i18n.errors,\n ...options?.errors,\n },\n attributes: {\n ...ctx.stash.__i18n.attributes,\n ...options?.attributes,\n },\n }\n : { errors: options?.errors, attributes: options?.attributes }) as {\n errors: Partial<ValidationErrors>\n attributes: Partial<Record<`:${NestedKeyOf<T>}`, string>>\n }\n if (getHeader('precognition', ctx) !== 'true')\n return ctx.stash.__validated = validate<T>(ctx.args, checks, { ...options, errors, attributes })\n\n const validationKeys = getHeader('Precognition-Validate-Only', ctx)?.split(',').map(key => key.trim())\n util.http.addResponseHeader('Precognition', 'true')\n\n if (!validationKeys) {\n ctx.stash.__validated = validate(ctx.args, checks, { ...options, errors, attributes })\n util.http.addResponseHeader('Precognition-Success', 'true')\n runtime.earlyReturn(null)\n }\n\n util.http.addResponseHeader('Precognition-Validate-Only', validationKeys.join(','))\n const precognitionChecks = {} as Partial<typeof checks>\n validationKeys.forEach((key) => {\n precognitionChecks[key as keyof typeof precognitionChecks] = checks[key as keyof typeof checks]\n })\n\n ctx.stash.__validated = validate(ctx.args, precognitionChecks, { ...options, errors, attributes })\n util.http.addResponseHeader('Precognition-Success', 'true')\n runtime.earlyReturn(null, { skipTo: options?.skipTo ?? 'END' })\n}\n\nexport function validationError<T = any>(\n msg: string,\n options?: { path?: NestedKeyOf<T>, value?: any },\n): never {\n util.error(msg, 'ValidationError', null, { ...options })\n}\n\nexport function appendValidationError<T = any>(\n msg: string,\n options?: { path?: NestedKeyOf<T>, value?: any },\n): void {\n util.appendError(msg, 'ValidationError', null, { ...options })\n}\n\nexport function formatAttributeName(path: string): string {\n return path.split('.').reduce((acc, part) => {\n if (util.matches('^\\\\d+$', part)) {\n return acc\n }\n let words = ''\n part.split('').forEach((char, idx) => {\n if (idx !== 0 && util.matches('[A-Z]', char)) {\n words += ' '\n }\n words += char.toLowerCase()\n })\n return acc ? `${acc} ${words}` : words\n }, '')\n}\n\nexport function assertValidated<\n T extends { [key in keyof T]: T[key] },\n>(\n ctx: Ctx<Partial<T>>,\n): asserts ctx is typeof ctx & {\n stash: { __validated: T }\n} {\n if (Object.hasOwn(ctx.stash, '__validated'))\n return\n util.error('Context arguments have not been validated')\n}\n\nexport function isLocalized<\n T extends { [key in keyof T]: T[key] },\n TLocale extends string,\n>(\n ctx: Ctx<Partial<T>>,\n locale?: TLocale,\n): ctx is typeof ctx & {\n stash: typeof ctx.stash & {\n __i18n: I18n<T, string>\n }\n} {\n if (Object.hasOwn(ctx.stash, '__i18n') && typeof ctx.stash?.__i18n.locale === 'string') {\n return locale\n ? ctx.stash.__i18n.locale === locale\n : true\n }\n return false\n}\n\nexport function assertLocalized<\n T extends { [key in keyof T]: T[key] },\n TLocale extends string,\n>(\n ctx: Ctx<Partial<T>>,\n locale?: TLocale,\n): asserts ctx is typeof ctx & {\n stash: typeof ctx.stash & {\n __i18n: I18n<T, string>\n }\n} {\n if (isLocalized<T, TLocale>(ctx, locale))\n return\n util.error('Context arguements have not been localized')\n}\n\nexport type { CustomFullRule, FullRule, I18n, Rule, ValidationErrors } from './types'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["rules.parse","rules.sometimesRule"],"sources":["../src/rules.ts","../src/index.ts"],"sourcesContent":["import type { CustomFullRule, FullRule, ParsedRule, ParseOptions } from './types'\nimport { util } from '@aws-appsync/utils'\nimport { date, datetime, email, integer, isArray, numeric, phone, time, ulid, url, uuid } from './utils'\n\nconst regexRules = {\n email,\n phone,\n url,\n uuid,\n ulid,\n integer,\n date,\n time,\n datetime,\n numeric,\n} as const\n\nexport function parse<T>(\n opt: ParseOptions<T>,\n rule: FullRule | CustomFullRule,\n): ParsedRule<T> {\n const [n, ...p] = typeof rule === 'string'\n ? [rule, undefined]\n : isArray(rule)\n ? [rule[0], ...rule.slice(1)]\n : typeof rule.rule === 'string'\n ? [rule.rule, undefined]\n : [rule.rule[0], ...rule.rule.slice(1)]\n\n switch (n) {\n case 'required':\n return requiredRule(opt)\n case 'nullable':\n return nullableRule(opt)\n case 'sometimes':\n util.error('sometimes rule is not allowed here')\n break\n case 'min':\n case 'bigger':\n return betweenRule(opt, (p[0]! as number), undefined, n === 'bigger')\n case 'max':\n case 'lower':\n return betweenRule(opt, undefined, (p[0] as number), n === 'lower')\n case 'between':\n case 'within':\n return betweenRule(opt, (p[0] as number), p[1] as number, n === 'within')\n case 'regex':\n return regexRule(opt, ...p as string[])\n case 'in':\n return inRule(opt, ...p)\n case 'notIn':\n return notInRule(opt, ...p)\n case 'before':\n case 'beforeOrEqual':\n return beforeRule(opt, p[0] as string, n === 'before')\n case 'after':\n case 'afterOrEqual':\n return afterRule(opt, p[0] as string, n === 'after')\n case 'email':\n case 'phone':\n case 'url':\n case 'uuid':\n case 'ulid':\n case 'integer':\n case 'date':\n case 'time':\n case 'datetime':\n case 'numeric':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors[n] }, regexRules[n])\n case 'unique':\n return uniqueRule(opt)\n default:\n return typeRule(opt, n)\n }\n}\n\nfunction betweenRule<T>(\n { value, msg, errors }: ParseOptions<T>,\n minV: number = -Infinity,\n maxV: number = Infinity,\n strict = false,\n): ParsedRule<T> {\n const [min, max] = [maxV === Infinity, minV === -Infinity]\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? min\n ? strict\n ? errors.biggerNumber\n : errors.minNumber\n : max\n ? strict\n ? errors.lowerNumber\n : errors.maxNumber\n : strict\n ? errors.withinNumber\n : errors.betweenNumber,\n value,\n params: {\n ':min': `${minV}`,\n ':max': `${maxV}`,\n },\n }\n if (typeof value === 'number')\n result.check = strict ? value > minV && value < maxV : value >= minV && value <= maxV\n\n if (typeof value === 'string') {\n result.check = value.length >= minV && value.length <= maxV\n result.msg = msg ?? min\n ? errors.minString\n : max\n ? errors.maxString\n : errors.betweenString\n }\n if (isArray(value)) {\n result.check = value.length >= minV && value.length <= maxV\n result.msg = msg ?? min\n ? errors.minArray\n : max\n ? errors.maxArray\n : errors.betweenArray\n }\n return result\n}\n\nfunction regexRule<T>(opt: ParseOptions<T>, ...pat: string[]): ParsedRule<T> {\n const res: ParsedRule<T> = {\n check: false,\n msg: opt.msg ?? opt.errors.regex,\n value: opt.value,\n }\n if (typeof opt.value === 'string' || typeof opt.value === 'number') {\n const valStr = typeof opt.value === 'string' ? opt.value : `${opt.value}`\n pat.forEach((p) => {\n res.check = res.check || util.matches(p, valStr)\n })\n }\n return res\n}\n\nfunction inRule<T>({ value, msg, errors }: ParseOptions<T>, ...p: unknown[]): ParsedRule<T> {\n return {\n check: p.includes(value),\n msg: msg ?? errors.in,\n value,\n params: { ':in': p.join(', ') },\n }\n}\n\nfunction notInRule<T>({ value, msg, errors }: ParseOptions<T>, ...p: unknown[]): ParsedRule<T> {\n return {\n check: !p.includes(value),\n msg: msg ?? errors.notIn,\n value,\n params: { ':notIn': p.join(', ') },\n }\n}\n\nexport function requiredRule<T>({ value, msg, errors }: ParseOptions<T>): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: true,\n msg: msg ?? errors.required,\n value,\n skipNext: true,\n }\n if (typeof value === 'string')\n result.check = value.length > 0\n if (isArray(value))\n result.check = value.length > 0\n if (typeof value === 'number')\n result.check = true\n if (typeof value === 'boolean')\n result.check = true\n if (typeof value === 'object' && !result.value) {\n result.check = false\n }\n if (typeof value === 'undefined')\n result.check = false\n result.skipNext = !result.check\n return result\n}\n\nfunction nullableRule<T>({ value, msg, errors }: ParseOptions<T>): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: true,\n msg: msg ?? errors.nullable,\n value,\n skipNext: typeof value === 'undefined' || value === null,\n }\n return result\n}\n\nexport function sometimesRule<T>({ value, msg, errors, parent, key }: ParseOptions<T> & { parent: object, key: string }): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: true,\n msg: msg ?? errors.sometimes,\n value,\n }\n if (!Object.hasOwn(parent, key)) {\n result.skipNext = true\n return result\n }\n if (typeof value === 'object' && !result.value) {\n result.check = false\n result.skipNext = true\n return result\n }\n return requiredRule({ value, msg, errors })\n}\n\nfunction typeRule<T>({ value, msg, errors }: ParseOptions<T>, type: 'boolean' | 'object' | 'array' | 'number' | 'string'): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? errors.type,\n value,\n params: { ':type': type },\n }\n switch (type) {\n case 'array':\n result.check = isArray(value)\n break\n case 'object':\n result.check = typeof value === 'object' && !!value && !isArray(value) && Object.keys(value).length > 0\n break\n case 'boolean':\n result.check = typeof value === 'boolean'\n break\n case 'number':\n result.check = typeof value === 'number'\n break\n default:\n result.check = typeof value === 'string'\n }\n return result\n}\n\nfunction beforeRule<T>({ value, msg, errors }: ParseOptions<T>, start: string, strict = false): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? errors.before,\n value,\n params: strict\n ? { ':before': start }\n : { ':beforeOrEqual': start },\n }\n const compareValue = typeof value === 'number'\n ? util.time.epochMilliSecondsToISO8601(value > 10000000000 ? value : value * 1000)\n : value\n if (typeof compareValue !== 'string')\n return result\n result.check = strict ? compareValue < start : compareValue <= start\n return result\n}\n\nfunction afterRule<T>({ value, msg, errors }: ParseOptions<T>, p: string, strict = false): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? strict ? errors.after : errors.afterOrEqual,\n value,\n params: strict\n ? { ':after': p }\n : { ':afterOrEqual': p },\n }\n const compareValue = typeof value === 'number'\n ? util.time.epochMilliSecondsToISO8601(value > 10000000000 ? value : value * 1000)\n : value\n if (typeof compareValue !== 'string')\n return result\n result.check = strict ? compareValue > p : compareValue >= p\n return result\n}\n\nfunction uniqueRule<T>({ value, msg, errors }: ParseOptions<T>): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? errors.unique,\n value,\n }\n if (isArray(value)) {\n const occurrences: Record<string, number> = {}\n value.forEach((item) => {\n const key = typeof item === 'string' ? item : `${item}`\n occurrences[key] = (occurrences[key] || 0) + 1\n })\n result.check = Object.values(occurrences).every(count => count === 1)\n }\n return result\n}\n","import type { Ctx, CustomFullRule, FullRule, I18n, NestedKeyOf, Rule, ValidationErrors } from './types'\nimport { runtime, util } from '@aws-appsync/utils'\nimport * as rules from './rules'\nimport { baseErrors, cleanString, getHeader, getNestedValue, isArray, isParentPathValid, parseErrorMessage, setNestedValue } from './utils'\n\nfunction isRule(rule: FullRule | CustomFullRule | Omit<Rule, 'value'>): rule is Omit<Rule, 'value'> {\n return typeof rule === 'object' && !!rule && Object.hasOwn(rule, 'check')\n}\n\nfunction isCustomFullRule(rule: FullRule | CustomFullRule | Omit<Rule, 'value'>): rule is CustomFullRule {\n return typeof rule === 'object' && !!rule && Object.hasOwn(rule, 'rule')\n}\n\nexport function validate<T>(\n obj: Readonly<Partial<T>>,\n checks: Partial<{\n [key in NestedKeyOf<T>]: Array<\n | FullRule\n | CustomFullRule\n | Omit<Rule<T>, 'value'>\n > }>,\n options?: {\n trim?: boolean\n allowEmptyString?: boolean\n errors?: Partial<ValidationErrors>\n attributes?: Partial<Record<`:${NestedKeyOf<T>}`, string>>\n },\n): T {\n let error: { msg?: string, errorType?: string, data?: any, errorInfo?: any } = {}\n const errors: ValidationErrors = { ...baseErrors, ...options?.errors }\n if (typeof obj !== 'object' || !obj)\n util.error('Object expected')\n\n sanitizeNestedArray(obj, checks)\n if (options?.attributes)\n sanitizeNestedArray(obj, options.attributes)\n\n const validated: T & object = JSON.parse(JSON.stringify(obj))\n Object.keys(checks).forEach((path) => {\n if (path.split('.').length > 1) {\n const parentPath = path.split('.').slice(0, -1).join('.')\n if (!isParentPathValid(validated, parentPath))\n return\n }\n\n let value = getNestedValue(validated, path)\n const parent: object = path.split('.').length > 1\n ? getNestedValue(validated, path.split('.').slice(0, -1).join('.'))\n : validated\n if (typeof value === 'string') {\n value = cleanString(value, options)\n setNestedValue(validated, path as NestedKeyOf<T>, value)\n }\n\n let skip: boolean = false\n const keyRules = checks[path as keyof typeof checks]\n if (keyRules?.length) {\n keyRules.forEach((rule) => {\n if (skip)\n return\n\n const result = isRule(rule)\n ? { ...rule, value, msg: rule.msg ?? errors.invalid }\n : isCustomFullRule(rule)\n ? rules.parse({ value, msg: rule.msg, errors }, rule.rule)\n : rule === 'sometimes'\n ? rules.sometimesRule({ value, errors, parent, key: path.split('.').pop()! })\n : rules.parse({ value, errors }, rule)\n\n skip = !!result.skipNext || !result.check\n\n if (result.check)\n return\n\n if (error.msg)\n appendValidationError(error.msg, { ...error.errorInfo })\n\n result.params = result.params ?? {}\n\n if (util.matches(':attr', result.msg))\n result.params[':attr'] = options?.attributes?.[`:${path as NestedKeyOf<T>}`] ?? formatAttributeName(path as NestedKeyOf<T>)\n\n error = {\n msg: parseErrorMessage(result.msg, result.params),\n errorType: 'ValidationError',\n data: null,\n errorInfo: { path, value },\n }\n })\n }\n })\n\n if (!error.msg) {\n return validated as T\n }\n\n validationError(error.msg, { ...error.errorInfo })\n}\n\nfunction sanitizeNestedArray(\n obj: object,\n nested: object,\n): void {\n let maxKeys: string[] = []\n Object.keys(nested).forEach((path: string) => {\n const currentKeys = path.split('.').filter(k => k === '*')\n if (currentKeys.length > maxKeys.length) {\n maxKeys = [...currentKeys]\n }\n })\n\n maxKeys.forEach(() => {\n Object.keys(nested).forEach((path) => {\n const keys = path.split('.')\n const wildcardIdx = keys.indexOf('*', 1)\n\n if (wildcardIdx < 1)\n return\n\n const parentPath = keys.slice(0, wildcardIdx).join('.')\n const cleanParentPath = parentPath.startsWith(':') ? parentPath.slice(1) : parentPath\n\n if (!isParentPathValid(obj, cleanParentPath)) {\n delete nested[path as keyof typeof nested]\n return\n }\n\n const parentValue = getNestedValue(obj, cleanParentPath)\n\n if (!isArray(parentValue)) {\n delete nested[path as keyof typeof nested]\n return\n }\n\n parentValue.forEach((_, i) => {\n const idxPath = [...keys]\n idxPath[wildcardIdx] = `${i}`\n nested[idxPath.join('.') as keyof typeof nested] = nested[path as keyof typeof nested]\n })\n delete nested[path as keyof typeof nested]\n })\n })\n}\n\nexport function precognitiveValidation<T>(\n ctx: Ctx<Partial<T>>,\n checks: Partial<{\n [key in NestedKeyOf<T>]: Array<\n | FullRule\n | CustomFullRule\n | Omit<Rule, 'value'>\n > }>,\n options?: {\n trim?: boolean\n allowEmptyString?: boolean\n skipTo?: 'END' | 'NEXT'\n errors?: Partial<ValidationErrors>\n attributes?: Partial<Record<`:${NestedKeyOf<T>}`, string>>\n },\n): T {\n const { errors, attributes } = (isLocalized<T, string>(ctx)\n ? {\n errors: {\n ...ctx.stash.__i18n.errors,\n ...options?.errors,\n },\n attributes: {\n ...ctx.stash.__i18n.attributes,\n ...options?.attributes,\n },\n }\n : { errors: options?.errors, attributes: options?.attributes }) as {\n errors: Partial<ValidationErrors>\n attributes: Partial<Record<`:${NestedKeyOf<T>}`, string>>\n }\n if (getHeader('precognition', ctx) !== 'true')\n return ctx.stash.__validated = validate<T>(ctx.args, checks, { ...options, errors, attributes })\n\n const validationKeys = getHeader('Precognition-Validate-Only', ctx)?.split(',').map(key => key.trim())\n util.http.addResponseHeader('Precognition', 'true')\n\n if (!validationKeys) {\n ctx.stash.__validated = validate(ctx.args, checks, { ...options, errors, attributes })\n util.http.addResponseHeader('Precognition-Success', 'true')\n runtime.earlyReturn(null)\n }\n\n util.http.addResponseHeader('Precognition-Validate-Only', validationKeys.join(','))\n const precognitionChecks = {} as Partial<typeof checks>\n validationKeys.forEach((key) => {\n precognitionChecks[key as keyof typeof precognitionChecks] = checks[key as keyof typeof checks]\n })\n\n ctx.stash.__validated = validate(ctx.args, precognitionChecks, { ...options, errors, attributes })\n util.http.addResponseHeader('Precognition-Success', 'true')\n runtime.earlyReturn(null, { skipTo: options?.skipTo ?? 'END' })\n}\n\nexport function validationError<T = any>(\n msg: string,\n options?: { path?: NestedKeyOf<T>, value?: any },\n): never {\n util.error(msg, 'ValidationError', null, { ...options })\n}\n\nexport function appendValidationError<T = any>(\n msg: string,\n options?: { path?: NestedKeyOf<T>, value?: any },\n): void {\n util.appendError(msg, 'ValidationError', null, { ...options })\n}\n\nexport function formatAttributeName(path: string): string {\n return path.split('.').reduce((acc, part) => {\n if (util.matches('^\\\\d+$', part)) {\n return acc\n }\n let words = ''\n part.split('').forEach((char, idx) => {\n if (idx !== 0 && util.matches('[A-Z]', char)) {\n words += ' '\n }\n words += char.toLowerCase()\n })\n return acc ? `${acc} ${words}` : words\n }, '')\n}\n\nexport function assertValidated<\n T extends { [key in keyof T]: T[key] },\n>(\n ctx: Ctx<Partial<T>>,\n): asserts ctx is typeof ctx & {\n stash: { __validated: T }\n} {\n if (Object.hasOwn(ctx.stash, '__validated'))\n return\n util.error('Context arguments have not been validated')\n}\n\nexport function isLocalized<\n T extends { [key in keyof T]: T[key] },\n TLocale extends string,\n>(\n ctx: Ctx<Partial<T>>,\n locale?: TLocale,\n): ctx is typeof ctx & {\n stash: typeof ctx.stash & {\n __i18n: I18n<T, string>\n }\n} {\n if (Object.hasOwn(ctx.stash, '__i18n') && typeof ctx.stash?.__i18n.locale === 'string') {\n return locale\n ? ctx.stash.__i18n.locale === locale\n : true\n }\n return false\n}\n\nexport function assertLocalized<\n T extends { [key in keyof T]: T[key] },\n TLocale extends string,\n>(\n ctx: Ctx<Partial<T>>,\n locale?: TLocale,\n): asserts ctx is typeof ctx & {\n stash: typeof ctx.stash & {\n __i18n: I18n<T, string>\n }\n} {\n if (isLocalized<T, TLocale>(ctx, locale))\n return\n util.error('Context arguements have not been localized')\n}\n\nexport type { CustomFullRule, FullRule, I18n, Rule, ValidationErrors } from './types'\n"],"mappings":"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"}
|