@sot1986/appsync-precognition 0.3.2 → 0.4.0

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.d.ts CHANGED
@@ -1,20 +1,37 @@
1
- import { n as NestedKeyOf, r as Rule, t as FullRule } from "./types-1ORDfyL5.js";
1
+ import { a as Rule, i as NestedKeyOf, o as ValidationErrors, r as FullRule, t as CustomFullRule } from "./types-zu_QN-gu.js";
2
2
 
3
3
  //#region src/index.d.ts
4
- declare function validate<T extends { [key in keyof T & string]: T[key] }>(obj: Partial<T>, checks: Partial<Record<NestedKeyOf<T>, (FullRule | Rule<T>)[]>>, options?: {
4
+ declare function validate<T extends { [key in keyof T & string]: T[key] }>(obj: Partial<T>, checks: Partial<Record<NestedKeyOf<T>, (FullRule | CustomFullRule<T> | Rule<T>)[]>>, options?: {
5
5
  trim?: boolean;
6
6
  allowEmptyString?: boolean;
7
+ errors?: Partial<ValidationErrors>;
7
8
  }): T;
8
9
  declare function precognitiveValidation<T extends { [key in keyof T & string]: T[key] }>(ctx: {
9
10
  request: {
10
11
  headers: any;
11
12
  };
12
13
  args: Partial<T>;
13
- }, checks: Partial<Record<NestedKeyOf<T>, (FullRule | Rule<T>)[]>>, options?: {
14
+ stash: Record<string, any>;
15
+ }, checks: Partial<Record<NestedKeyOf<T>, (FullRule | CustomFullRule<T> | Rule<T>)[]>>, options?: {
14
16
  trim?: boolean;
15
17
  allowEmptyString?: boolean;
16
18
  skipTo?: "END" | "NEXT";
17
19
  }): T;
18
20
  declare function formatAttributeName(path: string): string;
21
+ declare function assertValidated<T extends { [key in keyof T & string]: T[key] }>(ctx: {
22
+ request: {
23
+ headers: any;
24
+ };
25
+ args: Partial<T>;
26
+ stash: Record<string, any>;
27
+ }): asserts ctx is {
28
+ request: {
29
+ headers: any;
30
+ };
31
+ args: Partial<T>;
32
+ stash: Record<string, any> & {
33
+ __validated: T;
34
+ };
35
+ };
19
36
  //#endregion
20
- export { formatAttributeName, precognitiveValidation, validate };
37
+ export { assertValidated, formatAttributeName, precognitiveValidation, validate };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;iBAKgB,mCAAmC,aAAa,EAAE,aAC3D,QAAQ,YACL,QAAQ,OAAO,YAAY,KAAK,WAAW,KAAK,gBAFP;;EAAnD,gBAAgB,CAAA,EAAA,OAAA;CAAmC,CAAA,EAOhD,CAPgD;AAAa,iBAmDhD,sBAnDgD,CAAA,UAAA,UAAA,MAoDpC,CApDoC,GAAA,MAAA,GAoDvB,CApDuB,CAoDrB,GApDqB,CAAA,EAAA,CAAA,CAAA,GAAA,EAAA;EAAE,OAAA,EAAA;IACnD,OAAA,EAAA,GAAA;EAAR,CAAA;EAC8B,IAAA,EAoDK,OApDL,CAoDa,CApDb,CAAA;CAAZ,EAAA,MAAA,EAqDf,OArDe,CAqDP,MArDO,CAqDA,WArDA,CAqDY,CArDZ,CAAA,EAAA,CAqDiB,QArDjB,GAqD4B,IArD5B,CAqDiC,CArDjC,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,OAAP,CAAO,EAAA;EAAiB,IAAA,CAAA,EAAA,OAAA;EAAgB,gBAAA,CAAA,EAAA,OAAA;EAAL,MAAA,CAAA,EAAA,KAAA,GAAA,MAAA;CAAnC,CAAA,EA2Df,CA3De;AAAR,iBAmFM,mBAAA,CAnFN,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;iBAagB,mCAAmC,aAAa,EAAE,aAC3D,QAAQ,YACL,QAAQ,OAAO,YAAY,KAAK,WAAW,eAAe,KAAK,KAAK,gBAFd;;EAAhE,gBAAgB,CAAA,EAAA,OAAA;EAAmC,MAAA,CAAA,EAMtC,OANsC,CAM9B,gBAN8B,CAAA;CAAa,CAAA,EAQ7D,CAR6D;AAAE,iBA8ElD,sBA9EkD,CAAA,UAAA,UAAA,MA+EtC,CA/EsC,GAAA,MAAA,GA+EzB,CA/EyB,CA+EvB,GA/EuB,CAAA,EAAA,CAAA,CAAA,GAAA,EAAA;EACnD,OAAA,EAAA;IAAR,OAAA,EAAA,GAAA;EAC8B,CAAA;EAAZ,IAAA,EA+EiB,OA/EjB,CA+EyB,CA/EzB,CAAA;EAAiB,KAAA,EA+EmB,MA/EnB,CAAA,MAAA,EAAA,GAAA,CAAA;CAA0B,EAAA,MAAA,EAgF1D,OAhF0D,CAgFlD,MAhFkD,CAgF3C,WAhF2C,CAgF/B,CAhF+B,CAAA,EAAA,CAgF1B,QAhF0B,GAgFf,cAhFe,CAgFA,CAhFA,CAAA,GAgFK,IAhFL,CAgFU,CAhFV,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,OAAlD,CAAkD,EAAA;EAAf,IAAA,CAAA,EAAA,OAAA;EAAyB,gBAAA,CAAA,EAAA,OAAA;EAAL,MAAA,CAAA,EAAA,KAAA,GAAA,MAAA;CAAvD,CAAA,EAsFf,CAtFe;AAAR,iBAgHM,mBAAA,CAhHN,IAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAIW,iBA4HL,eA5HK,CAAA,UAAA,UAAA,MA6HO,CA7HP,GAAA,MAAA,GA6HoB,CA7HpB,CA6HsB,GA7HtB,CAAA,EAAA,CAAA,CAAA,GAAA,EAAA;EAAR,OAAA,EAAA;IAEV,OAAA,EAAA,GAAA;EAAA,CAAA;EAsEH,IAAgB,EAuD0B,OAvD1B,CAuDkC,CAvDlC,CAAA;EACY,KAAA,EAsDiC,MAtDjC,CAAA,MAAA,EAAA,GAAA,CAAA;CAAa,CAAA,EAAA,QAAA,GAAA,IAAA;EAAE,OAAA,EAAA;IAEO,OAAA,EAAA,GAAA;EAAR,CAAA;EAAmB,IAAA,EAqDR,OArDQ,CAqDA,CArDA,CAAA;EACxB,KAAA,EAoDmC,MApDnC,CAAA,MAAA,EAAA,GAAA,CAAA,GAAA;IAAZ,WAAA,EAoDoF,CApDpF;EAAiB,CAAA;CAA0B"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{cleanString,getHeader,getNestedValue,isArray,setNestedValue}from"./utils.js";import{runtime,util}from"@aws-appsync/utils";function parse(e,d){const[f,...p]=typeof d===`string`?[d,void 0]:[d[0],...d.slice(1)];switch(f){case`required`:return requiredRule(e);case`nullable`:return nullableRule(e);case`sometimes`:return sometimesRule(e);case`min`:return betweenRule(e,p[0]);case`max`:return betweenRule(e,void 0,p[0]);case`between`:return betweenRule(e,p[0],p[1]);case`regex`:return regexRule(e,...p);case`in`:return inRule(e,...p);case`notIn`:return notInRule(e,...p);case`before`:return beforeRule(e,p[0]);case`after`:return afterRule(e,p[0]);case`beforeOrEqual`:return beforeOrEqualRule(e,p[0]);case`afterOrEqual`:return afterOrEqualRule(e,p[0]);default:return typeRule(e,f)}}function betweenRule(e,d=-Infinity,f=Infinity){const[m,h]=[d===-Infinity,f===Infinity];const g={check:false,message:m?`:attribute should be at most ${f}`:h?`:attribute should be at least ${d}`:`:attribute must be between ${d} and ${f}`,value:e};if(typeof e===`number`)g.check=e>=d&&e<=f;if(typeof e===`string`){g.check=e.length>=d&&e.length<=f;g.message=m?`String must not exceed ${f} characters`:h?`String must contain at least ${d} characters`:`String must contain between ${d} and ${f} characters`}if(isArray(e)){g.check=e.length>=d&&e.length<=f;g.message=m?`Array must not contain more than ${f} elements`:h?`Array must contain at least ${d} elements`:`Array must contain between ${d} and ${f} elements`}return g}function regexRule(e,...d){const f={check:false,message:`:attribute must match the specified regular expression`,value:e};if(typeof e===`string`)f.check=d.some(d=>util.matches(d,e));return f}function inRule(e,...d){return{check:d.includes(e),message:`:attribute must be one of the specified values`,value:e}}function notInRule(e,...d){return{check:!d.includes(e),message:`:attribute must not be one of the specified values`,value:e}}function requiredRule(e){const d={check:true,message:`:attribute is required`,value:e,skipNext:true};if(typeof e===`string`)d.check=e.length>0;if(isArray(e))d.check=e.length>0;if(typeof e===`number`)d.check=true;if(typeof e===`boolean`)d.check=true;if(typeof e===`object`&&!d.value){d.message=`:attribute is not nullable`;d.check=false}if(typeof e===`undefined`)d.check=false;d.skipNext=!d.check;return d}function nullableRule(e){return{check:true,message:`:attribute must be nullable`,value:e,skipNext:typeof e===`undefined`||e===null}}function sometimesRule(e){const d={check:true,message:`:attribute is not nullable`,value:e};if(typeof e===`undefined`){d.skipNext=true;return d}if(typeof e===`object`&&!d.value){d.check=false;d.skipNext=true;return d}return requiredRule(e)}function typeRule(e,d){const f={check:false,message:`:attribute must be a ${d}`,value:e};switch(d){case`array`:f.check=isArray(e);break;case`object`:f.check=typeof e===`object`&&!!e&&!isArray(e)&&Object.keys(e).length>0;break;case`boolean`:f.check=typeof e===`boolean`;break;case`number`:f.check=typeof e===`number`;break;default:f.check=typeof e===`string`}return f}function beforeRule(e,d){const f={check:false,message:`:attribute must be before ${d}`,value:e};const p=util.time.parseISO8601ToEpochMilliSeconds(d);if(typeof e===`string`)f.check=util.time.parseISO8601ToEpochMilliSeconds(e)<p;if(typeof e===`number`)f.check=e<p;return f}function afterRule(e,d){const f={check:false,message:`:attribute must be after ${d}`,value:e};const p=util.time.parseISO8601ToEpochMilliSeconds(d);if(typeof e===`string`)f.check=util.time.parseISO8601ToEpochMilliSeconds(e)>p;if(typeof e===`number`)f.check=e>p;return f}function beforeOrEqualRule(e,d){const f={check:false,message:`:attribute must be before or equal to ${d}`,value:e};const p=util.time.parseISO8601ToEpochMilliSeconds(d);if(typeof e===`string`)f.check=util.time.parseISO8601ToEpochMilliSeconds(e)<=p;if(typeof e===`number`)f.check=e<=p;return f}function afterOrEqualRule(e,d){const f={check:false,message:`:attribute must be after or equal to ${d}`,value:e};const p=util.time.parseISO8601ToEpochMilliSeconds(d);if(typeof e===`string`)f.check=util.time.parseISO8601ToEpochMilliSeconds(e)>=p;if(typeof e===`number`)f.check=e>=p;return f}function validate(d,h,v){let y={};Object.keys(h).forEach(b=>{let x=getNestedValue(d,b);if(typeof x===`string`){x=cleanString(x,v);setNestedValue(d,b,x)}let S=false;h[b]?.forEach(e=>{if(S)return;const d=typeof e===`string`||isArray(e)?parse(x,e):{...e};S=!!d.skipNext||!d.check;if(d.check)return;if(y.msg)util.appendError(y.msg,y.errorType,y.data,y.errorInfo);d.message=d.message.replace(`:attribute`,formatAttributeName(b));y={msg:d.message,errorType:`ValidationError`,data:null,errorInfo:{path:b,value:x}}})});if(!y.msg)return d;util.error(y.msg,y.errorType,y.data,y.errorInfo)}function precognitiveValidation(e,f,p){if(getHeader(`precognition`,e)!==`true`)return validate(e.args,f,p);const m=getHeader(`Precognition-Validate-Only`,e)?.split(`,`).map(e=>e.trim());util.http.addResponseHeader(`Precognition`,`true`);if(!m){validate(e.args,f,p);util.http.addResponseHeader(`Precognition-Success`,`true`);runtime.earlyReturn(null)}util.http.addResponseHeader(`Precognition-Validate-Only`,m.join(`,`));const _={};m.forEach(e=>{_[e]=f[e]});validate(e.args,_,p);util.http.addResponseHeader(`Precognition-Success`,`true`);runtime.earlyReturn(null,{skipTo:p?.skipTo??`END`})}function formatAttributeName(e){return e.split(`.`).reduce((e,d)=>{if(util.matches(`^\\d+$`,d))return e;let f=``;d.split(``).forEach((e,d)=>{if(d!==0&&util.matches(`[A-Z]`,e))f+=` `;f+=e.toLowerCase()});return e?`${e} ${f}`:f},``)}export{formatAttributeName,precognitiveValidation,validate};
1
+ import{baseErrors,cleanString,date,datetime,email,getHeader,getNestedValue,integer,isArray,numeric,parseErrorMessage,phone,setNestedValue,time,ulid,url,uuid}from"./utils.js";import{runtime,util}from"@aws-appsync/utils";function parse(c,D){const[j,...M]=typeof D===`string`?[D,void 0]:isArray(D)?[D[0],...D.slice(1)]:typeof D.rule===`string`?[D.rule,void 0]:[D.rule[0],...D.rule.slice(1)];switch(j){case`required`:return requiredRule(c);case`nullable`:return nullableRule(c);case`sometimes`:return sometimesRule(c);case`min`:case`bigger`:return betweenRule(c,M[0],void 0,j===`bigger`);case`max`:case`lower`:return betweenRule(c,void 0,M[0],j===`lower`);case`between`:case`within`:return betweenRule(c,M[0],M[1],j===`within`);case`regex`:return regexRule(c,...M);case`in`:return inRule(c,...M);case`notIn`:return notInRule(c,...M);case`before`:case`beforeOrEqual`:return beforeRule(c,M[0],j===`before`);case`after`:case`afterOrEqual`:return afterRule(c,M[0],j===`after`);case`email`:return regexRule({...c,msg:c.msg??c.errors.email},email);case`phone`:return regexRule({...c,msg:c.msg??c.errors.phone},phone);case`url`:return regexRule({...c,msg:c.msg??c.errors.url},url);case`uuid`:return regexRule({...c,msg:c.msg??c.errors.uuid},uuid);case`ulid`:return regexRule({...c,msg:c.msg??c.errors.ulid},ulid);case`integer`:return regexRule({...c,msg:c.msg??c.errors.integer},integer);case`date`:return regexRule({...c,msg:c.msg??c.errors.date},date);case`time`:return regexRule({...c,msg:c.msg??c.errors.time},time);case`datetime`:return regexRule({...c,msg:c.msg??c.errors.datetime},datetime);case`numeric`:return regexRule({...c,msg:c.msg??c.errors.numeric},numeric);default:return typeRule(c,j)}}function betweenRule({value:c,msg:D,errors:O},k=-Infinity,A=Infinity,j=false){const[M,N]=[k===-Infinity,A===Infinity];const F={check:false,msg:D??M?j?O.biggerNumber:O.minNumber:N?j?O.lowerNumber:O.maxNumber:j?O.withinNumber:O.betweenNumber,value:c};if(typeof c===`number`)F.check=j?c>k&&c<A:c>=k&&c<=A;if(typeof c===`string`){F.check=c.length>=k&&c.length<=A;F.msg=D??M?O.minString:N?O.maxString:O.betweenString}if(isArray(c)){F.check=c.length>=k&&c.length<=A;F.msg=D??M?O.minArray:N?O.maxArray:O.betweenArray}return F}function regexRule({value:c,msg:D,errors:O},...k){const A={check:false,msg:D??(k.length===1?O.regex:O.regex_patterns),value:c,params:k.length===1?{":pattern":k[0]}:{":patterns":k.join(`, `)}};if(typeof c===`string`)A.check=k.some(D=>util.matches(D,c));if(typeof c===`number`)A.check=k.some(D=>util.matches(D,`${c}`));return A}function inRule({value:c,msg:D,errors:O},...k){return{check:k.includes(c),msg:D??O.in,value:c,params:{":in":k.join(`, `)}}}function notInRule({value:c,msg:D,errors:O},...k){return{check:!k.includes(c),msg:D??O.notIn,value:c,params:{":notIn":k.join(`, `)}}}function requiredRule({value:c,msg:D,errors:O}){const k={check:true,msg:D??O.required,value:c,skipNext:true};if(typeof c===`string`)k.check=c.length>0;if(isArray(c))k.check=c.length>0;if(typeof c===`number`)k.check=true;if(typeof c===`boolean`)k.check=true;if(typeof c===`object`&&!k.value)k.check=false;if(typeof c===`undefined`)k.check=false;k.skipNext=!k.check;return k}function nullableRule({value:c,msg:D,errors:O}){return{check:true,msg:D??O.nullable,value:c,skipNext:typeof c===`undefined`||c===null}}function sometimesRule({value:c,msg:D,errors:O}){const k={check:true,msg:D??O.sometimes,value:c};if(typeof c===`undefined`){k.skipNext=true;return k}if(typeof c===`object`&&!k.value){k.check=false;k.skipNext=true;return k}return requiredRule({value:c,msg:D,errors:O})}function typeRule({value:c,msg:D,errors:O},k){const A={check:false,msg:D??O.type,value:c,params:{":type":k}};switch(k){case`array`:A.check=isArray(c);break;case`object`:A.check=typeof c===`object`&&!!c&&!isArray(c)&&Object.keys(c).length>0;break;case`boolean`:A.check=typeof c===`boolean`;break;case`number`:A.check=typeof c===`number`;break;default:A.check=typeof c===`string`}return A}function beforeRule({value:c,msg:D,errors:O},k,A=false){const j={check:false,msg:D??O.before,value:c,params:A?{":before":k}:{":beforeOrEqual":k}};const M=util.time.parseISO8601ToEpochMilliSeconds(k);const N=typeof c===`string`?util.time.parseISO8601ToEpochMilliSeconds(c):c;if(typeof N===`number`)j.check=A?N<M:N<=M;return j}function afterRule({value:c,msg:D,errors:O},k,A=false){const j={check:false,msg:D??A?O.after:O.afterOrEqual,value:c,params:A?{":after":k}:{":afterOrEqual":k}};const M=util.time.parseISO8601ToEpochMilliSeconds(k);const N=typeof c===`string`?util.time.parseISO8601ToEpochMilliSeconds(c):c;if(typeof N===`number`)j.check=A?N>M:N>=M;return j}function isRule(c){return typeof c===`object`&&!!c&&Object.hasOwn(c,`check`)}function isCustomFullRule(c){return typeof c===`object`&&!!c&&Object.hasOwn(c,`rule`)}function validate(O,k,A){let j={};const N={...baseErrors,...A?.errors};Object.keys(k).forEach(c=>{const D=c.split(`.`);D.forEach((A,j)=>{if(A!==`*`||j===0)return;const N=getNestedValue(O,D.slice(0,j).join(`.`));if(!isArray(N))return;N.forEach((O,A)=>{const M=[...D];M[j]=`${A}`;k[M.join(`.`)]=k[c]});delete k[c]})});Object.keys(k).forEach(c=>{let P=getNestedValue(O,c);if(typeof P===`string`){P=cleanString(P,A);setNestedValue(O,c,P)}let F=false;k[c]?.forEach(D=>{if(F)return;const O=isRule(D)?{...D,msg:D.msg??N.invalid}:isCustomFullRule(D)?parse({value:P,msg:D.msg,errors:N},D.rule):parse({value:P,errors:N},D);F=!!O.skipNext||!O.check;if(O.check)return;if(j.msg)util.appendError(j.msg,j.errorType,j.data,j.errorInfo);O.params=O.params??{};if(util.matches(`:attr`,O.msg))O.params[`:attr`]=O.params[`:attr`]??formatAttributeName(c);j={msg:parseErrorMessage(O.msg,O.params),errorType:`ValidationError`,data:null,errorInfo:{path:c,value:P}}})});if(!j.msg)return O;util.error(j.msg,j.errorType,j.data,j.errorInfo)}function precognitiveValidation(c,D,O){if(getHeader(`precognition`,c)!==`true`){c.stash.__validated=validate(c.args,D,O);return c.stash.__validated}const k=getHeader(`Precognition-Validate-Only`,c)?.split(`,`).map(c=>c.trim());util.http.addResponseHeader(`Precognition`,`true`);if(!k){c.stash.__validated=validate(c.args,D,O);util.http.addResponseHeader(`Precognition-Success`,`true`);runtime.earlyReturn(null)}util.http.addResponseHeader(`Precognition-Validate-Only`,k.join(`,`));const A={};k.forEach(c=>{A[c]=D[c]});c.stash.__validated=validate(c.args,A,O);util.http.addResponseHeader(`Precognition-Success`,`true`);runtime.earlyReturn(null,{skipTo:O?.skipTo??`END`})}function formatAttributeName(c){return c.split(`.`).reduce((c,D)=>{if(util.matches(`^\\d+$`,D))return c;let O=``;D.split(``).forEach((c,D)=>{if(D!==0&&util.matches(`[A-Z]`,c))O+=` `;O+=c.toLowerCase()});return c?`${c} ${O}`:O},``)}function assertValidated(c){if(Object.hasOwn(c.stash,`__validated`))return;util.error(`Context arguements have not been validated`)}export{assertValidated,formatAttributeName,precognitiveValidation,validate};
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["result: Rule<T>","error: { msg?: string, errorType?: string, data?: any, errorInfo?: any }","rules.parse"],"sources":["../src/rules.ts","../src/index.ts"],"sourcesContent":["import type { FullRule, Rule } from './types'\nimport { util } from '@aws-appsync/utils'\nimport { isArray } from './utils'\n\nexport function parse<T>(value: T, rule: FullRule): Rule<T> {\n const [name, ...params] = typeof rule === 'string'\n ? [rule, undefined]\n : [rule[0], ...rule.slice(1)]\n\n switch (name) {\n case 'required':\n return requiredRule(value)\n case 'nullable':\n return nullableRule(value)\n case 'sometimes':\n return sometimesRule(value)\n case 'min':\n return betweenRule(value, (params[0]! as number))\n case 'max':\n return betweenRule(value, undefined, (params[0] as number))\n case 'between':\n return betweenRule(value, (params[0] as number), params[1] as number)\n case 'regex':\n return regexRule(value, ...params as string[])\n case 'in':\n return inRule(value, ...params)\n case 'notIn':\n return notInRule(value, ...params)\n case 'before':\n return beforeRule(value, params[0] as string)\n case 'after':\n return afterRule(value, params[0] as string)\n case 'beforeOrEqual':\n return beforeOrEqualRule(value, params[0] as string)\n case 'afterOrEqual':\n return afterOrEqualRule(value, params[0] as string)\n default:\n return typeRule(value, name)\n }\n}\n\nfunction betweenRule<T>(value: T, minValue: number = -Infinity, maxValue: number = Infinity): Rule<T> {\n const [min, max] = [minValue === -Infinity, maxValue === Infinity]\n const result: Rule<T> = {\n check: false,\n message: min ? `:attribute should be at most ${maxValue}` : max ? `:attribute should be at least ${minValue}` : `:attribute must be between ${minValue} and ${maxValue}`,\n value,\n }\n if (typeof value === 'number')\n result.check = value >= minValue && value <= maxValue\n if (typeof value === 'string') {\n result.check = value.length >= minValue && value.length <= maxValue\n result.message = min\n ? `String must not exceed ${maxValue} characters`\n : max\n ? `String must contain at least ${minValue} characters`\n : `String must contain between ${minValue} and ${maxValue} characters`\n }\n if (isArray(value)) {\n result.check = value.length >= minValue && value.length <= maxValue\n result.message = min\n ? `Array must not contain more than ${maxValue} elements`\n : max\n ? `Array must contain at least ${minValue} elements`\n : `Array must contain between ${minValue} and ${maxValue} elements`\n }\n return result\n}\n\nfunction regexRule<T>(value: T, ...patterns: string[]): Rule<T> {\n const result: Rule<T> = {\n check: false,\n message: ':attribute must match the specified regular expression',\n value,\n }\n if (typeof value === 'string') {\n result.check = patterns.some(pattern => util.matches(pattern, value))\n }\n return result\n}\n\nfunction inRule<T>(value: T, ...params: unknown[]): Rule<T> {\n return {\n check: params.includes(value),\n message: ':attribute must be one of the specified values',\n value,\n }\n}\n\nfunction notInRule<T>(value: T, ...params: unknown[]): Rule<T> {\n return {\n check: !params.includes(value),\n message: ':attribute must not be one of the specified values',\n value,\n }\n}\n\nexport function requiredRule<T>(value: T): Rule<T> {\n const result: Rule<T> = {\n check: true,\n message: ':attribute is 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.message = ':attribute is not nullable'\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: T): Rule<T> {\n const result: Rule<T> = {\n check: true,\n message: ':attribute must be nullable',\n value,\n skipNext: typeof value === 'undefined' || value === null,\n }\n return result\n}\n\nfunction sometimesRule<T>(value: T): Rule<T> {\n const result: Rule<T> = {\n check: true,\n message: ':attribute is not nullable',\n value,\n }\n if (typeof value === 'undefined') {\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)\n}\n\nfunction typeRule<T>(value: T, type: 'boolean' | 'object' | 'array' | 'number' | 'string'): Rule<T> {\n const result: Rule<T> = {\n check: false,\n message: `:attribute must be a ${type}`,\n value,\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: T, start: string): Rule<T> {\n const result: Rule<T> = {\n check: false,\n message: `:attribute must be before ${start}`,\n value,\n }\n const startValue = util.time.parseISO8601ToEpochMilliSeconds(start)\n\n if (typeof value === 'string') {\n const date = util.time.parseISO8601ToEpochMilliSeconds(value)\n result.check = date < startValue\n }\n\n if (typeof value === 'number') {\n result.check = value < startValue\n }\n return result\n}\n\nfunction afterRule<T>(value: T, start: string): Rule<T> {\n const result: Rule<T> = {\n check: false,\n message: `:attribute must be after ${start}`,\n value,\n }\n const startValue = util.time.parseISO8601ToEpochMilliSeconds(start)\n\n if (typeof value === 'string') {\n const date = util.time.parseISO8601ToEpochMilliSeconds(value)\n result.check = date > startValue\n }\n\n if (typeof value === 'number') {\n result.check = value > startValue\n }\n return result\n}\n\nfunction beforeOrEqualRule<T>(value: T, start: string): Rule<T> {\n const result: Rule<T> = {\n check: false,\n message: `:attribute must be before or equal to ${start}`,\n value,\n }\n const startValue = util.time.parseISO8601ToEpochMilliSeconds(start)\n\n if (typeof value === 'string') {\n const date = util.time.parseISO8601ToEpochMilliSeconds(value)\n result.check = date <= startValue\n }\n\n if (typeof value === 'number') {\n result.check = value <= startValue\n }\n return result\n}\n\nfunction afterOrEqualRule<T>(value: T, start: string): Rule<T> {\n const result: Rule<T> = {\n check: false,\n message: `:attribute must be after or equal to ${start}`,\n value,\n }\n const startValue = util.time.parseISO8601ToEpochMilliSeconds(start)\n\n if (typeof value === 'string') {\n const date = util.time.parseISO8601ToEpochMilliSeconds(value)\n result.check = date >= startValue\n }\n\n if (typeof value === 'number') {\n result.check = value >= startValue\n }\n return result\n}\n","import type { FullRule, NestedKeyOf, Rule } from './types'\nimport { runtime, util } from '@aws-appsync/utils'\nimport * as rules from './rules'\nimport { cleanString, getHeader, getNestedValue, isArray, setNestedValue } from './utils'\n\nexport function validate<T extends { [key in keyof T & string]: T[key] }>(\n obj: Partial<T>,\n checks: Partial<Record<NestedKeyOf<T>, (FullRule | Rule<T>)[]>>,\n options?: {\n trim?: boolean\n allowEmptyString?: boolean\n },\n): T {\n let error: { msg?: string, errorType?: string, data?: any, errorInfo?: any } = {}\n\n Object.keys(checks).forEach((path) => {\n let value = getNestedValue(obj, path as NestedKeyOf<T>)\n if (typeof value === 'string') {\n value = cleanString(value, options)\n setNestedValue(obj, path as NestedKeyOf<T>, value)\n }\n\n let skip = false\n checks[path as NestedKeyOf<T>]?.forEach((rule) => {\n if (skip)\n return\n\n const result = (typeof rule === 'string' || isArray(rule))\n ? rules.parse(value, rule)\n : { ...rule }\n\n skip = !!result.skipNext || !result.check\n\n if (result.check)\n return\n\n if (error.msg)\n util.appendError(error.msg, error.errorType, error.data, error.errorInfo)\n\n result.message = result.message.replace(':attribute', formatAttributeName(path))\n error = {\n msg: result.message,\n errorType: 'ValidationError',\n data: null,\n errorInfo: { path, value },\n }\n })\n })\n\n if (!error.msg) {\n return obj as T\n }\n\n util.error(error.msg, error.errorType, error.data, error.errorInfo)\n}\n\nexport function precognitiveValidation<\n T extends { [key in keyof T & string]: T[key] },\n>(\n ctx: { request: { headers: any }, args: Partial<T> },\n checks: Partial<Record<NestedKeyOf<T>, (FullRule | Rule<T>)[]>>,\n options?: {\n trim?: boolean\n allowEmptyString?: boolean\n skipTo?: 'END' | 'NEXT'\n },\n): T {\n if (getHeader('precognition', ctx) !== 'true') {\n return validate<T>(ctx.args, checks, options)\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 validate(ctx.args, checks, options)\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 NestedKeyOf<T>] = checks[key as NestedKeyOf<T>]\n })\n\n validate(ctx.args, precognitionChecks, options)\n util.http.addResponseHeader('Precognition-Success', 'true')\n runtime.earlyReturn(null, { skipTo: options?.skipTo ?? 'END' })\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"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["result: ParsedRule<T>","error: { msg?: string, errorType?: string, data?: any, errorInfo?: any }","result: ParsedRule<T>","rules.parse"],"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\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 return sometimesRule(opt)\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 return regexRule({ ...opt, msg: opt.msg ?? opt.errors.email }, email)\n case 'phone':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors.phone }, phone)\n case 'url':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors.url }, url)\n case 'uuid':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors.uuid }, uuid)\n case 'ulid':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors.ulid }, ulid)\n case 'integer':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors.integer }, integer)\n case 'date':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors.date }, date)\n case 'time':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors.time }, time)\n case 'datetime':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors.datetime }, datetime)\n case 'numeric':\n return regexRule({ ...opt, msg: opt.msg ?? opt.errors.numeric }, numeric)\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] = [minV === -Infinity, maxV === 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 }\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>({ value, msg, errors }: ParseOptions<T>, ...p: string[]): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: false,\n msg: msg ?? (p.length === 1 ? errors.regex : errors.regex_patterns),\n value,\n params: p.length === 1\n ? { ':pattern': p[0]! }\n : { ':patterns': p.join(', ') },\n }\n if (typeof value === 'string')\n result.check = p.some(pt => util.matches(pt, value))\n\n if (typeof value === 'number')\n result.check = p.some(pt => util.matches(pt, `${value}`))\n\n return result\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\nfunction sometimesRule<T>({ value, msg, errors }: ParseOptions<T>): ParsedRule<T> {\n const result: ParsedRule<T> = {\n check: true,\n msg: msg ?? errors.sometimes,\n value,\n }\n if (typeof value === 'undefined') {\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","import type { CustomFullRule, FullRule, NestedKeyOf, ParsedRule, Rule, ValidationErrors } from './types'\nimport { runtime, util } from '@aws-appsync/utils'\nimport * as rules from './rules'\nimport { baseErrors, cleanString, getHeader, getNestedValue, isArray, parseErrorMessage, setNestedValue } from './utils'\n\nfunction isRule<T>(rule: FullRule | CustomFullRule<T> | Rule<T>): rule is Rule<T> {\n return typeof rule === 'object' && !!rule && Object.hasOwn(rule, 'check')\n}\n\nfunction isCustomFullRule<T>(rule: FullRule | CustomFullRule<T> | Rule<T>): rule is CustomFullRule<T> {\n return typeof rule === 'object' && !!rule && Object.hasOwn(rule, 'rule')\n}\n\nexport function validate<T extends { [key in keyof T & string]: T[key] }>(\n obj: Partial<T>,\n checks: Partial<Record<NestedKeyOf<T>, (FullRule | CustomFullRule<T> | Rule<T>)[]>>,\n options?: {\n trim?: boolean\n allowEmptyString?: boolean\n errors?: Partial<ValidationErrors>\n },\n): T {\n let error: { msg?: string, errorType?: string, data?: any, errorInfo?: any } = {}\n const errors = { ...baseErrors, ...options?.errors }\n\n // Replace all array generic checks '*' with numbered checks\n Object.keys(checks).forEach((path) => {\n const keys = path.split('.')\n keys.forEach((k, idx) => {\n if (k !== '*' || idx === 0)\n return\n const parentPath = keys.slice(0, idx).join('.')\n const parentValue = getNestedValue(obj, parentPath as NestedKeyOf<T>)\n if (!isArray(parentValue))\n return\n\n parentValue.forEach((_, i) => {\n const idxPath = [...keys]\n idxPath[idx] = `${i}`\n checks[idxPath.join('.') as NestedKeyOf<T>] = checks[path as NestedKeyOf<T>]\n })\n delete checks[path as NestedKeyOf<T>]\n })\n })\n\n Object.keys(checks).forEach((path) => {\n let value = getNestedValue(obj, path as NestedKeyOf<T>)\n if (typeof value === 'string') {\n value = cleanString(value, options)\n setNestedValue(obj, path as NestedKeyOf<T>, value)\n }\n\n let skip = false\n checks[path as NestedKeyOf<T>]?.forEach((rule) => {\n if (skip)\n return\n\n const result: ParsedRule<T> = isRule(rule)\n ? { ...rule, msg: rule.msg ?? errors.invalid }\n : isCustomFullRule(rule)\n ? rules.parse<T>({ value, msg: rule.msg, errors }, rule.rule)\n : rules.parse<T>({ value, errors }, rule)\n\n skip = !!result.skipNext || !result.check\n\n if (result.check)\n return\n\n if (error.msg)\n util.appendError(error.msg, error.errorType, error.data, error.errorInfo)\n\n result.params = result.params ?? {}\n if (util.matches(':attr', result.msg))\n result.params[':attr'] = result.params[':attr'] ?? formatAttributeName(path)\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 if (!error.msg) {\n return obj as T\n }\n\n util.error(error.msg, error.errorType, error.data, error.errorInfo)\n}\n\nexport function precognitiveValidation<\n T extends { [key in keyof T & string]: T[key] },\n>(\n ctx: { request: { headers: any }, args: Partial<T>, stash: Record<string, any> },\n checks: Partial<Record<NestedKeyOf<T>, (FullRule | CustomFullRule<T> | Rule<T>)[]>>,\n options?: {\n trim?: boolean\n allowEmptyString?: boolean\n skipTo?: 'END' | 'NEXT'\n },\n): T {\n if (getHeader('precognition', ctx) !== 'true') {\n ctx.stash.__validated = validate<T>(ctx.args, checks, options)\n return ctx.stash.__validated\n }\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)\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 NestedKeyOf<T>] = checks[key as NestedKeyOf<T>]\n })\n\n ctx.stash.__validated = validate(ctx.args, precognitionChecks, options)\n util.http.addResponseHeader('Precognition-Success', 'true')\n runtime.earlyReturn(null, { skipTo: options?.skipTo ?? 'END' })\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 & string]: T[key] },\n>(\n ctx: { request: { headers: any }, args: Partial<T>, stash: Record<string, any> },\n): asserts ctx is { request: { headers: any }, args: Partial<T>, stash: Record<string, any> & { __validated: T } } {\n if (Object.hasOwn(ctx.stash, '__validated'))\n return\n util.error('Context arguements have not been validated')\n}\n"],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ //#region src/types.d.ts
2
+ type FullRule = "required" | "nullable" | "sometimes" | "number" | "boolean" | "string" | "array" | "object" | "url" | "email" | "uuid" | "ulid" | "date" | "datetime" | "time" | "integer" | "numeric" | "phone" | ["min", number] | ["max", number] | ["bigger", number] | ["lower", number] | ["between", number, number] | ["within", number, number] | ["regex", ...string[]] | ["in", ...(string | number | boolean | null)[]] | ["notIn", ...(string | number | boolean | null)[]] | ["after", string] | ["before", string] | ["afterOrEqual", string] | ["beforeOrEqual", string];
3
+ interface CustomFullRule<T = unknown> {
4
+ rule: FullRule;
5
+ value: T;
6
+ msg?: string;
7
+ skipNext?: boolean;
8
+ attribute?: string;
9
+ }
10
+ interface Rule<T = unknown> {
11
+ check: boolean;
12
+ value: T;
13
+ msg?: string;
14
+ skipNext?: boolean;
15
+ attribute?: string;
16
+ }
17
+ type ErrorMsgParams = Record<`:${string}`, string>;
18
+ interface ValidationErrors {
19
+ maxNumber: string;
20
+ minNumber: string;
21
+ betweenNumber: string;
22
+ biggerNumber: string;
23
+ lowerNumber: string;
24
+ withinNumber: string;
25
+ maxString: string;
26
+ minString: string;
27
+ betweenString: string;
28
+ minArray: string;
29
+ maxArray: string;
30
+ betweenArray: string;
31
+ in: string;
32
+ notIn: string;
33
+ email: string;
34
+ phone: string;
35
+ url: string;
36
+ uuid: string;
37
+ ulid: string;
38
+ date: string;
39
+ time: string;
40
+ datetime: string;
41
+ numeric: string;
42
+ integer: string;
43
+ type: string;
44
+ regex: string;
45
+ regex_patterns: string;
46
+ required: string;
47
+ nullable: string;
48
+ sometimes: string;
49
+ before: string;
50
+ beforeOrEqual: string;
51
+ after: string;
52
+ afterOrEqual: string;
53
+ invalid: string;
54
+ }
55
+ type ArrayKeys<T extends unknown[]> = T extends [unknown, ...unknown[]] ? T extends Record<infer Index, unknown> ? Index extends `${number}` ? Index | "*" : never : never : `${number}` | "*";
56
+ type ObjectKeys<T extends object> = T extends unknown[] ? ArrayKeys<T> : keyof T & string;
57
+ interface HasConstructor {
58
+ new (...args: unknown[]): unknown;
59
+ }
60
+ type NestedKeyOf<T> = T extends Record<infer Key, unknown> ? T extends HasConstructor ? never : T extends CallableFunction ? never : Key extends string | number ? (ObjectKeys<T> | (T[Key] extends object ? `${ObjectKeys<Pick<T, Key>>}.${NestedKeyOf<T[Key]>}` : T extends unknown[] ? T extends [unknown, ...unknown[]] ? never : T[number] extends object ? `${number}.${NestedKeyOf<T[number]>}` : never : never)) : never : never;
61
+ //#endregion
62
+ export { Rule as a, NestedKeyOf as i, ErrorMsgParams as n, ValidationErrors as o, FullRule as r, CustomFullRule as t };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-zu_QN-gu.d.ts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";AAEY,KAAA,QAAA,GAAA,UAAA,GAAA,UAAA,GAAA,WAAA,GAAA,QAAA,GAAA,SAAA,GAAA,QAAA,GAAA,OAAA,GAAA,QAAA,GAAA,KAAA,GAAA,OAAA,GAAA,MAAA,GAAA,MAAA,GAAA,MAAA,GAAA,UAAA,GAAA,MAAA,GAAA,SAAA,GAAA,SAAA,GAAA,OAAA,GAAA,CAAA,KAAA,EAAA,MAAA,CAAA,GAAA,CAAA,KAAA,EAAA,MAAA,CAAA,GAAA,CAAA,QAAA,EAAA,MAAA,CAAA,GAAA,CAAA,OAAA,EAAA,MAAA,CAAA,GAAA,CAAA,SAAA,EAAA,MAAA,EAAA,MAAA,CAAA,GAAA,CAAA,QAAA,EAAA,MAAA,EAAA,MAAA,CAAA,GAAA,CAAA,OAAA,EAAA,GAAA,MAAA,EAAA,CAAA,GAAA,CAAA,IAAA,EAAA,GAAA,CAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,IAAA,CAAA,EAAA,CAAA,GAAA,CAAA,OAAA,EAAA,GAAA,CAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,IAAA,CAAA,EAAA,CAAA,GAAA,CAAA,OAAA,EAAA,MAAA,CAAA,GAAA,CAAA,QAAA,EAAA,MAAA,CAAA,GAAA,CAAA,cAAA,EAAA,MAAA,CAAA,GAAA,CAAA,eAAA,EAAA,MAAA,CAAA;AAiCK,UAAA,cAAA,CAAA,IACT,OAAA,CACC,CAAA;EAMT,IAAiB,EAPT,QAOS;EAQjB,KAAY,EAdH,CAcG;EAUZ,GAAiB,CAAA,EAAA,MAAA;UA0DZ,CAAA,EAAA,OAAA;EACD,SAAA,CAAA,EAAA,MAAA;;AACY,UA9EC,IA8ED,CAAA,IAAA,OAAA,CAAA,CAAA;EAEN,KAAA,EAAA,OAAA;EAAA,KAAA,EA9ED,CA8EC;EAAA,GAKL,CAAA,EAAA,MAAA;EACD,QAAA,CAAA,EAAA,OAAA;EACY,SAAA,CAAA,EAAA,MAAA;;AACJ,KAhFA,cAAA,GAAiB,MAgFjB,CAAA,IAAA,MAAA,EAAA,EAAA,MAAA,CAAA;AASN,UA/EW,gBAAA,CA+EX;EAAU,SAAA,EAAA,MAAA;EAGM,SAAA,EAAA,MAAA;EAAX,aAAA,EAAA,MAAA;EAAiB,YAAA,EAAA,MAAA;EAAE,WAAA,EAAA,MAAA;EACG,YAAA,EAAA,MAAA;EAAG,SAAA,EAAA,MAAA;EAAR,SAAA,EAAA,MAAA;EAAX,aAAA,EAAA,MAAA;EAAwC,QAAA,EAAA,MAAA;EAAE,QAAA,EAAA,MAAA;EAAd,YAAA,EAAA,MAAA;EAC/B,EAAA,EAAA,MAAA;EACE,KAAA,EAAA,MAAA;EAEE,KAAA,EAAA,MAAA;EAC2B,KAAA,EAAA,MAAA;EAAZ,GAAA,EAAA,MAAA;EAAA,IAAA,EAAA,MAAA;;;;;;;;;;;;;;;;;;;KA9B5B,iCACD,oCACE,UAAU,2DAEN;KAKL,+BACD,sBACE,UAAU,WACJ;UAEF,cAAA;;;KAIE,iBAAiB,UAAU,6BACnC,UAAU,yBAER,UAAU,0DAGL,WAAW,MAAM,EAAE,yBACb,WAAW,KAAK,GAAG,SAAS,YAAY,EAAE,UAC7C,sBACE,4CAEE,wCACe,YAAY"}
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { n as NestedKeyOf } from "./types-1ORDfyL5.js";
1
+ import { i as NestedKeyOf, n as ErrorMsgParams, o as ValidationErrors } from "./types-zu_QN-gu.js";
2
2
 
3
3
  //#region src/utils.d.ts
4
4
  declare function isArray(value: unknown): value is unknown[];
@@ -24,5 +24,7 @@ declare const time = "^([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,6})?Z?$";
24
24
  declare const datetime = "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,6})?Z$";
25
25
  declare const numeric = "^-?\\d+(\\.\\d+)?$";
26
26
  declare const integer = "^-?\\d+$";
27
+ declare const baseErrors: ValidationErrors;
28
+ declare function parseErrorMessage(msg: string, params?: ErrorMsgParams): string;
27
29
  //#endregion
28
- export { cleanString, date, datetime, email, getHeader, getNestedValue, integer, isArray, numeric, phone, setNestedValue, time, toNumber, ulid, url, uuid };
30
+ export { baseErrors, cleanString, date, datetime, email, getHeader, getNestedValue, integer, isArray, numeric, parseErrorMessage, phone, setNestedValue, time, toNumber, ulid, url, uuid };
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","names":[],"sources":["../src/utils.ts"],"sourcesContent":[],"mappings":";;;iBAGgB,OAAA;iBAIA,yCAAyC,aAAa,EAAE,aAAa,QAAQ,UAAU,YAAY;AAJnG,iBAUA,cAVA,CAAA,UAAA,UAAA,MAUyC,CAVzC,GAAA,MAAA,GAUsD,CAVtD,CAUwD,GAVxD,CAAA,EAAA,CAAA,CAAA,GAAA,EAUqE,OAVrE,CAU6E,CAV7E,CAAA,EAAA,IAAA,EAUuF,WAVvF,CAUmG,CAVnG,CAAA,EAAA,KAAA,EAAA,OAAA,CAAA,EAAA,IAAA;AAIA,iBAmBA,SAAA,CAnBA,IAAA,EAAA,MAAA,EAAA,GAAA,EAAA;EAAyC,OAAA,EAAA;IAAa,OAAA,EAAA,GAAA;EAAE,CAAA;CAAqB,CAAA,EAAA,MAAA,GAAA,IAAA;AAAR,iBAyBrE,WAAA,CAzBqE,KAAA,EAAA,MAAA,EAAA,OAAkB,CAAlB,EAAA;EAA8B,IAAA,CAAA,EAAA,OAAA;EAAZ,gBAAA,CAAA,EAAA,OAAA;CAAA,CAAA,EAAA,MAAA,GAAA,IAAA;AAMvF,iBA+BA,QAAA,CA/BA,KAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAAyC,cA0C5C,IAAA,GA1C4C,gEAAA;AAAa,cA2CzD,IAAA,GA3CyD,0CAAA;AAAE,cA4C3D,GAAA,GA5C2D,qMAAA;AAAqB,cA6ChF,KAAA,GA7CgF,mDAAA;AAAR,cA8CxE,KAAA,GA9CwE,qBAAA;AAA8B,cA+CtG,IAAA,GA/CsG,iDAAA;AAAZ,cAgD1F,IAAA,GAhD0F,sDAAA;AAAA,cAiD1F,QAAA,GAjD0F,mGAAA;AAavF,cAqCH,OAAA,GArCG,oBAAA;AAMA,cAgCH,OAAA,GAhCG,UAAA"}
1
+ {"version":3,"file":"utils.d.ts","names":["baseErrors: ValidationErrors"],"sources":["../src/utils.ts"],"sourcesContent":[],"mappings":";;;iBAGgB,OAAA;iBAIA,yCAAyC,aAAa,EAAE,aAAa,QAAQ,UAAU,YAAY;AAJnG,iBAUA,cAVA,CAAA,UAAA,UAAA,MAUyC,CAVzC,GAAA,MAAA,GAUsD,CAVtD,CAUwD,GAVxD,CAAA,EAAA,CAAA,CAAA,GAAA,EAUqE,OAVrE,CAU6E,CAV7E,CAAA,EAAA,IAAA,EAUuF,WAVvF,CAUmG,CAVnG,CAAA,EAAA,KAAA,EAAA,OAAA,CAAA,EAAA,IAAA;AAIA,iBAmBA,SAAA,CAnBA,IAAA,EAAA,MAAA,EAAA,GAAA,EAAA;EAAyC,OAAA,EAAA;IAAa,OAAA,EAAA,GAAA;EAAE,CAAA;CAAqB,CAAA,EAAA,MAAA,GAAA,IAAA;AAAR,iBAyBrE,WAAA,CAzBqE,KAAA,EAAA,MAAA,EAAA,OAAkB,CAAlB,EAAA;EAA8B,IAAA,CAAA,EAAA,OAAA;EAAZ,gBAAA,CAAA,EAAA,OAAA;CAAA,CAAA,EAAA,MAAA,GAAA,IAAA;AAMvF,iBA+BA,QAAA,CA/BA,KAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAAyC,cA0C5C,IAAA,GA1C4C,gEAAA;AAAa,cA2CzD,IAAA,GA3CyD,0CAAA;AAAE,cA4C3D,GAAA,GA5C2D,qMAAA;AAAqB,cA6ChF,KAAA,GA7CgF,mDAAA;AAAR,cA8CxE,KAAA,GA9CwE,qBAAA;AAA8B,cA+CtG,IAAA,GA/CsG,iDAAA;AAAZ,cAgD1F,IAAA,GAhD0F,sDAAA;AAAA,cAiD1F,QAAA,GAjD0F,mGAAA;AAavF,cAqCH,OAAA,GArCG,oBAAA;AAMA,cAgCH,OAAA,GAhCG,UAAA;AAYA,cAsBHA,UAtBG,EAsBS,gBAtBT;AAWH,iBAiDG,iBAAA,CAjDH,GAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAiD2C,cAjD3C,CAAA,EAAA,MAAA"}
package/dist/utils.js CHANGED
@@ -1 +1 @@
1
- import{util}from"@aws-appsync/utils";function isArray(e){return typeof e===`object`&&!!e&&typeof e?.length===`number`}function getNestedValue(d,f){return f.split(`.`).reduce((d,f)=>util.matches(`^\\d+$`,f)?d[toNumber(f)]:d[f],d)}function setNestedValue(e,d,p){const m=d.split(`.`);if(m.length===1){e[m[0]]=p;return}const h=m.pop();const g=getNestedValue(e,m.join(`.`));if(typeof g===`object`&&!!g)g[h]=p}function getHeader(e,d){const f=e.toLowerCase();const p=Object.keys(d.request.headers).find(e=>e.toLowerCase()===f);return p?d.request.headers[p]:null}function cleanString(e,d){if(d?.trim===false)return e;const f=e.trim();if(d?.allowEmptyString)return f;return f===``?null:f}function toNumber(d){switch(true){case util.matches(`^(-|\\+)?\\d+(\\.\\d+)?$`,d):return+d;case util.matches(`^(-|\\+)?Infinity$`,d):return+d;default:util.error(`Invalid number: ${d}`)}}const uuid=`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`;const ulid=`^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$`;const url=`^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)$|^https?:\\/\\/(localhost|\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})(:\\d+)?(\\/.*)?$`;const email=`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$`;const phone=`^\\+[1-9]\\d{1,20}$`;const date=`^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$`;const time=`^([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,6})?Z?$`;const datetime=`^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,6})?Z$`;const numeric=`^-?\\d+(\\.\\d+)?$`;const integer=`^-?\\d+$`;export{cleanString,date,datetime,email,getHeader,getNestedValue,integer,isArray,numeric,phone,setNestedValue,time,toNumber,ulid,url,uuid};
1
+ import{util}from"@aws-appsync/utils";function isArray(e){return typeof e===`object`&&!!e&&typeof e?.length===`number`}function getNestedValue(p,m){return m.split(`.`).reduce((p,m)=>util.matches(`^\\d+$`,m)?p[toNumber(m)]:p[m],p)}function setNestedValue(e,p,h){const g=p.split(`.`);if(g.length===1){e[g[0]]=h;return}const _=g.pop();const v=getNestedValue(e,g.join(`.`));if(typeof v===`object`&&!!v)v[_]=h}function getHeader(e,p){const m=e.toLowerCase();const h=Object.keys(p.request.headers).find(e=>e.toLowerCase()===m);return h?p.request.headers[h]:null}function cleanString(e,p){if(p?.trim===false)return e;const m=e.trim();if(p?.allowEmptyString)return m;return m===``?null:m}function toNumber(p){switch(true){case util.matches(`^(-|\\+)?\\d+(\\.\\d+)?$`,p):return+p;case util.matches(`^(-|\\+)?Infinity$`,p):return+p;default:util.error(`Invalid number: ${p}`)}}const uuid=`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`;const ulid=`^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$`;const url=`^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._\\+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_\\+.~#?&//=]*)$|^https?:\\/\\/(localhost|\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})(:\\d+)?(\\/.*)?$`;const email=`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$`;const phone=`^\\+[1-9]\\d{1,20}$`;const date=`^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$`;const time=`^([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,6})?Z?$`;const datetime=`^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d{1,6})?Z$`;const numeric=`^-?\\d+(\\.\\d+)?$`;const integer=`^-?\\d+$`;const baseErrors={maxNumber:`:attr max value is :max`,minNumber:`:attr min value is :min`,betweenNumber:`:attr value must be between :min and :max`,biggerNumber:`:attr must be bigger than :min`,lowerNumber:`:attr must be lower than :max`,withinNumber:`:attr must be within :min and :max`,maxString:`:attr must not exceed :max characters`,minString:`:attr must have at least :min characters`,betweenString:`:attr must have between :min and :max characters`,minArray:`:attr must have at least :min elements`,maxArray:`:attr must have at most :max elements`,betweenArray:`:attr must have between :min and :max elements`,in:`:attr must be one of the specified values: :in`,notIn:`:attr must not be one of this list: :notIn`,email:`:attr must be a valid email address (name@domain.com)`,phone:`:attr must be a valid phone number (+123...)`,url:`:attr must be a valid URL (:pattern)`,uuid:`:attr must be a valid UUID (:pattern)`,ulid:`:attr must be a valid ULID (:pattern)`,date:`:attr must be a valid date (:pattern)`,time:`:attr must be a valid time (:pattern)`,datetime:`:attr must be a valid datetime (:pattern)`,numeric:`:attr must be a valid number (:pattern)`,integer:`:attr must be a valid integer (:pattern)`,type:`:attr is not valid :type`,regex:`:attr must match :pattern`,regex_patterns:`attr: must match any of :patterns`,required:`:attr is required`,nullable:`:attr is nullable`,sometimes:`:attr cannot be null`,before:`:attr must be before :before`,beforeOrEqual:`:attr must be before or equal to :beforeOrEqual`,after:`:attr must be after :after`,afterOrEqual:`:attr must be after or equal to :afterOrEqual`,invalid:`:attr is not valid`};function parseErrorMessage(e,p){let m=e;Object.entries(p??{}).forEach(([e,p])=>{m=m.replaceAll(e,p)});return m}export{baseErrors,cleanString,date,datetime,email,getHeader,getNestedValue,integer,isArray,numeric,parseErrorMessage,phone,setNestedValue,time,toNumber,ulid,url,uuid};
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["parsed: string | null"],"sources":["../src/utils.ts"],"sourcesContent":["import type { NestedKeyOf } from './types'\nimport { util } from '@aws-appsync/utils'\n\nexport function isArray(value: unknown): value is unknown[] {\n return typeof value === 'object' && !!value && typeof (value as unknown[] | undefined)?.length === 'number'\n}\n\nexport function getNestedValue<T extends { [key in keyof T & string]: T[key] }>(obj: Partial<T>, path: NestedKeyOf<T>): any {\n return path.split('.').reduce<unknown>((current, key) => util.matches('^\\\\d+$', key)\n ? (current as unknown[])[toNumber(key)]\n : (current as Record<string, unknown>)[key], obj)\n}\n\nexport function setNestedValue<T extends { [key in keyof T & string]: T[key] }>(obj: Partial<T>, path: NestedKeyOf<T>, value: unknown): void {\n const keys = path.split('.')\n if (keys.length === 1) {\n obj[keys[0] as keyof typeof obj] = value as any\n return\n }\n const lastKey = keys.pop() as string\n const parentObject = getNestedValue(obj, keys.join('.') as NestedKeyOf<T>)\n if (typeof parentObject === 'object' && !!parentObject) {\n parentObject[lastKey] = value\n }\n}\n\nexport function getHeader(name: string, ctx: { request: { headers: any } }): string | null {\n const lowerCaseName = name.toLowerCase()\n const key = Object.keys(ctx.request.headers).find(h => h.toLowerCase() === lowerCaseName)\n return key ? ctx.request.headers[key] : null\n}\n\nexport function cleanString(value: string, options?: {\n trim?: boolean\n allowEmptyString?: boolean\n}): string | null {\n if (options?.trim === false)\n return value\n const parsed: string | null = value.trim()\n if (options?.allowEmptyString)\n return parsed\n return parsed === '' ? null : parsed\n}\n\nexport function toNumber(value: string): number {\n switch (true) {\n case util.matches('^(-|\\\\+)?\\\\d+(\\\\.\\\\d+)?$', value):\n return +value\n case util.matches('^(-|\\\\+)?Infinity$', value):\n return +value\n default:\n util.error(`Invalid number: ${value}`)\n }\n}\n\nexport const uuid = `^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`\nexport const ulid = '^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$'\nexport const url = '^https?:\\\\/\\\\/(www\\\\.)?[-a-zA-Z0-9@:%._\\\\+~#=]{1,256}\\\\.[a-zA-Z0-9()]{1,6}\\\\b([-a-zA-Z0-9()@:%_\\\\+.~#?&//=]*)$|^https?:\\\\/\\\\/(localhost|\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3})(:\\\\d+)?(\\\\/.*)?$'\nexport const email = '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$'\nexport const phone = '^\\\\+[1-9]\\\\d{1,20}$'\nexport const date = '^\\\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01])$'\nexport const time = '^([01]\\\\d|2[0-3]):[0-5]\\\\d:[0-5]\\\\d(\\\\.\\\\d{1,6})?Z?$'\nexport const datetime = '^\\\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01])T([01]\\\\d|2[0-3]):[0-5]\\\\d:[0-5]\\\\d(\\\\.\\\\d{1,6})?Z$'\nexport const numeric = '^-?\\\\d+(\\\\.\\\\d+)?$'\nexport const integer = '^-?\\\\d+$'\n"],"mappings":"qCAGA,SAAgB,QAAQ,EAAoC,CAC1D,OAAO,OAAO,IAAU,UAAY,CAAC,CAAC,GAAS,OAAQ,GAAiC,SAAW,SAGrG,SAAgB,eAAgE,EAAiB,EAA2B,CAC1H,OAAO,EAAK,MAAM,IAAI,CAAC,QAAiB,EAAS,IAAQ,KAAK,QAAQ,SAAU,EAAI,CAC/E,EAAsB,SAAS,EAAI,EACnC,EAAoC,GAAM,EAAI,CAGrD,SAAgB,eAAgE,EAAiB,EAAsB,EAAsB,CAC3I,MAAM,EAAO,EAAK,MAAM,IAAI,CAC5B,GAAI,EAAK,SAAW,EAAG,CACrB,EAAI,EAAK,IAA0B,EACnC,OAEF,MAAM,EAAU,EAAK,KAAK,CAC1B,MAAM,EAAe,eAAe,EAAK,EAAK,KAAK,IAAI,CAAmB,CAC1E,GAAI,OAAO,IAAiB,UAAY,CAAC,CAAC,EACxC,EAAa,GAAW,EAI5B,SAAgB,UAAU,EAAc,EAAmD,CACzF,MAAM,EAAgB,EAAK,aAAa,CACxC,MAAM,EAAM,OAAO,KAAK,EAAI,QAAQ,QAAQ,CAAC,KAAK,GAAK,EAAE,aAAa,GAAK,EAAc,CACzF,OAAO,EAAM,EAAI,QAAQ,QAAQ,GAAO,KAG1C,SAAgB,YAAY,EAAe,EAGzB,CAChB,GAAI,GAAS,OAAS,MACpB,OAAO,EACT,MAAMA,EAAwB,EAAM,MAAM,CAC1C,GAAI,GAAS,iBACX,OAAO,EACT,OAAO,IAAW,GAAK,KAAO,EAGhC,SAAgB,SAAS,EAAuB,CAC9C,OAAQ,KAAR,CACE,KAAK,KAAK,QAAQ,2BAA4B,EAAM,CAClD,MAAO,CAAC,EACV,KAAK,KAAK,QAAQ,qBAAsB,EAAM,CAC5C,MAAO,CAAC,EACV,QACE,KAAK,MAAM,mBAAmB,IAAQ,EAI5C,MAAa,KAAO,iEACpB,MAAa,KAAO,2CACpB,MAAa,IAAM,sMACnB,MAAa,MAAQ,oDACrB,MAAa,MAAQ,sBACrB,MAAa,KAAO,kDACpB,MAAa,KAAO,uDACpB,MAAa,SAAW,oGACxB,MAAa,QAAU,qBACvB,MAAa,QAAU"}
1
+ {"version":3,"file":"utils.js","names":["parsed: string | null","baseErrors: ValidationErrors"],"sources":["../src/utils.ts"],"sourcesContent":["import type { ErrorMsgParams, NestedKeyOf, ValidationErrors } from './types'\nimport { util } from '@aws-appsync/utils'\n\nexport function isArray(value: unknown): value is unknown[] {\n return typeof value === 'object' && !!value && typeof (value as unknown[] | undefined)?.length === 'number'\n}\n\nexport function getNestedValue<T extends { [key in keyof T & string]: T[key] }>(obj: Partial<T>, path: NestedKeyOf<T>): any {\n return path.split('.').reduce<unknown>((current, key) => util.matches('^\\\\d+$', key)\n ? (current as unknown[])[toNumber(key)]\n : (current as Record<string, unknown>)[key], obj)\n}\n\nexport function setNestedValue<T extends { [key in keyof T & string]: T[key] }>(obj: Partial<T>, path: NestedKeyOf<T>, value: unknown): void {\n const keys = path.split('.')\n if (keys.length === 1) {\n obj[keys[0] as keyof typeof obj] = value as any\n return\n }\n const lastKey = keys.pop() as string\n const parentObject = getNestedValue(obj, keys.join('.') as NestedKeyOf<T>)\n if (typeof parentObject === 'object' && !!parentObject) {\n parentObject[lastKey] = value\n }\n}\n\nexport function getHeader(name: string, ctx: { request: { headers: any } }): string | null {\n const lowerCaseName = name.toLowerCase()\n const key = Object.keys(ctx.request.headers).find(h => h.toLowerCase() === lowerCaseName)\n return key ? ctx.request.headers[key] : null\n}\n\nexport function cleanString(value: string, options?: {\n trim?: boolean\n allowEmptyString?: boolean\n}): string | null {\n if (options?.trim === false)\n return value\n const parsed: string | null = value.trim()\n if (options?.allowEmptyString)\n return parsed\n return parsed === '' ? null : parsed\n}\n\nexport function toNumber(value: string): number {\n switch (true) {\n case util.matches('^(-|\\\\+)?\\\\d+(\\\\.\\\\d+)?$', value):\n return +value\n case util.matches('^(-|\\\\+)?Infinity$', value):\n return +value\n default:\n util.error(`Invalid number: ${value}`)\n }\n}\n\nexport const uuid = `^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`\nexport const ulid = '^[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}$'\nexport const url = '^https?:\\\\/\\\\/(www\\\\.)?[-a-zA-Z0-9@:%._\\\\+~#=]{1,256}\\\\.[a-zA-Z0-9()]{1,6}\\\\b([-a-zA-Z0-9()@:%_\\\\+.~#?&//=]*)$|^https?:\\\\/\\\\/(localhost|\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3})(:\\\\d+)?(\\\\/.*)?$'\nexport const email = '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$'\nexport const phone = '^\\\\+[1-9]\\\\d{1,20}$'\nexport const date = '^\\\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01])$'\nexport const time = '^([01]\\\\d|2[0-3]):[0-5]\\\\d:[0-5]\\\\d(\\\\.\\\\d{1,6})?Z?$'\nexport const datetime = '^\\\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\\\d|3[01])T([01]\\\\d|2[0-3]):[0-5]\\\\d:[0-5]\\\\d(\\\\.\\\\d{1,6})?Z$'\nexport const numeric = '^-?\\\\d+(\\\\.\\\\d+)?$'\nexport const integer = '^-?\\\\d+$'\n\nexport const baseErrors: ValidationErrors = {\n maxNumber: ':attr max value is :max',\n minNumber: ':attr min value is :min',\n betweenNumber: ':attr value must be between :min and :max',\n biggerNumber: ':attr must be bigger than :min',\n lowerNumber: ':attr must be lower than :max',\n withinNumber: ':attr must be within :min and :max',\n maxString: ':attr must not exceed :max characters',\n minString: ':attr must have at least :min characters',\n betweenString: ':attr must have between :min and :max characters',\n minArray: ':attr must have at least :min elements',\n maxArray: ':attr must have at most :max elements',\n betweenArray: ':attr must have between :min and :max elements',\n in: ':attr must be one of the specified values: :in',\n notIn: ':attr must not be one of this list: :notIn',\n email: ':attr must be a valid email address (name@domain.com)',\n phone: ':attr must be a valid phone number (+123...)',\n url: ':attr must be a valid URL (:pattern)',\n uuid: ':attr must be a valid UUID (:pattern)',\n ulid: ':attr must be a valid ULID (:pattern)',\n date: ':attr must be a valid date (:pattern)',\n time: ':attr must be a valid time (:pattern)',\n datetime: ':attr must be a valid datetime (:pattern)',\n numeric: ':attr must be a valid number (:pattern)',\n integer: ':attr must be a valid integer (:pattern)',\n type: ':attr is not valid :type',\n regex: ':attr must match :pattern',\n regex_patterns: 'attr: must match any of :patterns',\n required: ':attr is required',\n nullable: ':attr is nullable',\n sometimes: ':attr cannot be null',\n before: ':attr must be before :before',\n beforeOrEqual: ':attr must be before or equal to :beforeOrEqual',\n after: ':attr must be after :after',\n afterOrEqual: ':attr must be after or equal to :afterOrEqual',\n invalid: ':attr is not valid',\n}\n\nexport function parseErrorMessage(msg: string, params?: ErrorMsgParams): string {\n let parsedMsg = msg\n Object.entries(params ?? {}).forEach(([key, value]) => {\n parsedMsg = parsedMsg.replaceAll(key, value)\n })\n return parsedMsg\n}\n"],"mappings":"qCAGA,SAAgB,QAAQ,EAAoC,CAC1D,OAAO,OAAO,IAAU,UAAY,CAAC,CAAC,GAAS,OAAQ,GAAiC,SAAW,SAGrG,SAAgB,eAAgE,EAAiB,EAA2B,CAC1H,OAAO,EAAK,MAAM,IAAI,CAAC,QAAiB,EAAS,IAAQ,KAAK,QAAQ,SAAU,EAAI,CAC/E,EAAsB,SAAS,EAAI,EACnC,EAAoC,GAAM,EAAI,CAGrD,SAAgB,eAAgE,EAAiB,EAAsB,EAAsB,CAC3I,MAAM,EAAO,EAAK,MAAM,IAAI,CAC5B,GAAI,EAAK,SAAW,EAAG,CACrB,EAAI,EAAK,IAA0B,EACnC,OAEF,MAAM,EAAU,EAAK,KAAK,CAC1B,MAAM,EAAe,eAAe,EAAK,EAAK,KAAK,IAAI,CAAmB,CAC1E,GAAI,OAAO,IAAiB,UAAY,CAAC,CAAC,EACxC,EAAa,GAAW,EAI5B,SAAgB,UAAU,EAAc,EAAmD,CACzF,MAAM,EAAgB,EAAK,aAAa,CACxC,MAAM,EAAM,OAAO,KAAK,EAAI,QAAQ,QAAQ,CAAC,KAAK,GAAK,EAAE,aAAa,GAAK,EAAc,CACzF,OAAO,EAAM,EAAI,QAAQ,QAAQ,GAAO,KAG1C,SAAgB,YAAY,EAAe,EAGzB,CAChB,GAAI,GAAS,OAAS,MACpB,OAAO,EACT,MAAMA,EAAwB,EAAM,MAAM,CAC1C,GAAI,GAAS,iBACX,OAAO,EACT,OAAO,IAAW,GAAK,KAAO,EAGhC,SAAgB,SAAS,EAAuB,CAC9C,OAAQ,KAAR,CACE,KAAK,KAAK,QAAQ,2BAA4B,EAAM,CAClD,MAAO,CAAC,EACV,KAAK,KAAK,QAAQ,qBAAsB,EAAM,CAC5C,MAAO,CAAC,EACV,QACE,KAAK,MAAM,mBAAmB,IAAQ,EAI5C,MAAa,KAAO,iEACpB,MAAa,KAAO,2CACpB,MAAa,IAAM,sMACnB,MAAa,MAAQ,oDACrB,MAAa,MAAQ,sBACrB,MAAa,KAAO,kDACpB,MAAa,KAAO,uDACpB,MAAa,SAAW,oGACxB,MAAa,QAAU,qBACvB,MAAa,QAAU,WAEvB,MAAaC,WAA+B,CAC1C,UAAW,0BACX,UAAW,0BACX,cAAe,4CACf,aAAc,iCACd,YAAa,gCACb,aAAc,qCACd,UAAW,wCACX,UAAW,2CACX,cAAe,mDACf,SAAU,yCACV,SAAU,wCACV,aAAc,iDACd,GAAI,iDACJ,MAAO,6CACP,MAAO,wDACP,MAAO,+CACP,IAAK,uCACL,KAAM,wCACN,KAAM,wCACN,KAAM,wCACN,KAAM,wCACN,SAAU,4CACV,QAAS,0CACT,QAAS,2CACT,KAAM,2BACN,MAAO,4BACP,eAAgB,oCAChB,SAAU,oBACV,SAAU,oBACV,UAAW,uBACX,OAAQ,+BACR,cAAe,kDACf,MAAO,6BACP,aAAc,gDACd,QAAS,qBACV,CAED,SAAgB,kBAAkB,EAAa,EAAiC,CAC9E,IAAI,EAAY,EAChB,OAAO,QAAQ,GAAU,EAAE,CAAC,CAAC,SAAS,CAAC,EAAK,KAAW,CACrD,EAAY,EAAU,WAAW,EAAK,EAAM,EAC5C,CACF,OAAO"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sot1986/appsync-precognition",
3
3
  "type": "module",
4
- "version": "0.3.2",
4
+ "version": "0.4.0",
5
5
  "description": "JavaScript resolver validation utilities for AWS AppSync",
6
6
  "author": "sot1986",
7
7
  "license": "MIT",
@@ -1,16 +0,0 @@
1
- //#region src/types.d.ts
2
- interface Rule<T = unknown> {
3
- check: boolean;
4
- message: string;
5
- value: T;
6
- skipNext?: boolean;
7
- }
8
- type FullRule = "required" | "nullable" | "sometimes" | "number" | "boolean" | "string" | "array" | "object" | ["min", number] | ["max", number] | ["between", number, number] | ["regex", ...string[]] | ["in", ...(string | number | boolean | null)[]] | ["notIn", ...(string | number | boolean | null)[]] | ["after", string] | ["before", string] | ["afterOrEqual", string] | ["beforeOrEqual", string];
9
- type ArrayKeys<T extends unknown[]> = T extends [unknown, ...unknown[]] ? T extends Record<infer Index, unknown> ? Index extends `${number}` ? Index : never : never : `${number}`;
10
- type ObjectKeys<T extends object> = T extends unknown[] ? ArrayKeys<T> : keyof T & string;
11
- interface HasConstructor {
12
- new (...args: unknown[]): unknown;
13
- }
14
- type NestedKeyOf<T> = T extends Record<infer Key, unknown> ? T extends HasConstructor ? never : T extends CallableFunction ? never : Key extends string | number ? (ObjectKeys<T> | (T[Key] extends object ? `${ObjectKeys<Pick<T, Key>>}.${NestedKeyOf<T[Key]>}` : T extends unknown[] ? T extends [unknown, ...unknown[]] ? never : T[number] extends object ? `${number}.${NestedKeyOf<T[number]>}` : never : never)) : never : never;
15
- //#endregion
16
- export { NestedKeyOf as n, Rule as r, FullRule as t };
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-1ORDfyL5.d.ts","names":[],"sources":["../src/types.ts"],"sourcesContent":[],"mappings":";AAEiB,UAAA,IAAA,CAAA,IAGR,OAAA,CAAA,CAAA;EAIT,KAAY,EAAA,OAAA;EAkBL,OAEF,EAAA,MAAA;EACD,KAAA,EAzBK,CAyBL;EACE,QAAA,CAAA,EAAA,OAAA;;AAAU,KAtBJ,QAAA,GAsBI,UAAA,GAAA,UAAA,GAAA,WAAA,GAAA,QAAA,GAAA,SAAA,GAAA,QAAA,GAAA,OAAA,GAAA,QAAA,GAAA,CAAA,KAAA,EAAA,MAAA,CAAA,GAAA,CAAA,KAAA,EAAA,MAAA,CAAA,GAAA,CAAA,SAAA,EAAA,MAAA,EAAA,MAAA,CAAA,GAAA,CAAA,OAAA,EAAA,GAAA,MAAA,EAAA,CAAA,GAAA,CAAA,IAAA,EAAA,GAAA,CAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,IAAA,CAAA,EAAA,CAAA,GAAA,CAAA,OAAA,EAAA,GAAA,CAAA,MAAA,GAAA,MAAA,GAAA,OAAA,GAAA,IAAA,CAAA,EAAA,CAAA,GAAA,CAAA,OAAA,EAAA,MAAA,CAAA,GAAA,CAAA,QAAA,EAAA,MAAA,CAAA,GAAA,CAAA,cAAA,EAAA,MAAA,CAAA,GAAA,CAAA,eAAA,EAAA,MAAA,CAAA;AAAA,KAFX,SASA,CAAA,UAAA,OAAA,EAAA,CAAA,GARD,CAQC,SAAA,CAAA,OAAA,EAAA,GAAA,OAAA,EAAA,CAAA,GAPC,CAOD,SAPW,MAOX,CAAA,KAAA,MAAA,EAAA,OAAA,CAAA,GAAA,KAAA,SAAA,GAAA,MAAA,EAAA,GAAA,KAAA,GAAA,KAAA,GAAA,KAAA,GAAA,GAAA,MAAA,EAAA;KAAA,UACD,CAAA,UAAA,MAAA,CAAA,GAAA,CAAA,SAAA,OAAA,EAAA,GACE,SADF,CACY,CADZ,CAAA,GAAA,MAEQ,CAFR,GAAA,MAAA;UAIM,cAAA,CAHM;EAAV,KAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,OAAA;;AACM,KAMA,WANA,CAAA,CAAA,CAAA,GAMiB,CANjB,SAM2B,MAN3B,CAAA,KAAA,IAAA,EAAA,OAAA,CAAA,GAOR,CAPQ,SAOE,cAPF,GAAA,KAAA,GASN,CATM,SASI,gBATJ,GAAA,KAAA,GAAA,GAAA,SAAA,MAAA,GAAA,MAAA,GAAA,CAYD,UAZC,CAYU,CAZV,CAAA,GAAA,CAYgB,CAZhB,CAYkB,GAZlB,CAAA,SAAA,MAAA,GAAA,GAaK,UAbL,CAagB,IAbhB,CAaqB,CAbrB,EAawB,GAbxB,CAAA,CAAA,IAaiC,WAbjC,CAa6C,CAb7C,CAa+C,GAb/C,CAAA,CAAA,EAAA,GAcE,CAdF,SAAA,OAAA,EAAA,GAeI,CAfJ,SAAA,CAAA,OAAA,EAAA,GAAA,OAAA,EAAA,CAAA,GAAA,KAAA,GAiBM,CAjBN,CAAA,MAAA,CAAA,SAAA,MAAA,GAAA,GAAA,MAAA,IAkBqB,WAlBrB,CAkBiC,CAlBjC,CAAA,MAAA,CAAA,CAAA,EAAA,GAAA,KAAA,GAAA,KAAA,CAAA,CAAA,GAAA,KAAA,GAAA,KAAA"}