@jdlien/validator-utils 1.1.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/README.md +79 -0
- package/dist/validator-utils.js +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Validator Utils
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
This package is a library of utility functions that can be used for validating and sanitizing
|
|
6
|
+
strings and numbers, especially for use in forms. This package is the dependency for the [@jdlien/validator package](https://github.com/jdlien/validator).
|
|
7
|
+
|
|
8
|
+
This package was separated from Validator so that it could be used in other projects without
|
|
9
|
+
pulling in the entire Validator package if you only need some of its validation and parsing functions without the form validation and error message functionality.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @jdlien/validator-utils
|
|
15
|
+
|
|
16
|
+
# or
|
|
17
|
+
|
|
18
|
+
yarn add @jdlien/validator-utils
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Utility Functions
|
|
22
|
+
|
|
23
|
+
Validator includes several utility functions that may be useful in your own code, so they are exported as part of the module.
|
|
24
|
+
If you wish to use these, you may import the functions directly from the module as an object that contains all the functions:
|
|
25
|
+
|
|
26
|
+
```javascript
|
|
27
|
+
import { validatorUtils } from '@jdlien/validator'
|
|
28
|
+
// you could assign the functions you need to more convenient variables
|
|
29
|
+
const { dateFormat, formatDateTime } = validatorUtils
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Here is a list of the utility functions:
|
|
33
|
+
|
|
34
|
+
- **isFormControl**: Determines if an element is an HTML input, select, or textarea element.
|
|
35
|
+
- **isType**: Checks if an element has a type or data-type attribute matching one of the passed values.
|
|
36
|
+
- **momentToFPFormat**: Converts a moment.js-style format string to the flatpickr format.
|
|
37
|
+
- **monthToNumber**: Converts month string or number to a zero-based month number (January == 0).
|
|
38
|
+
- **yearToFull**: Converts a year string or number to a 4-digit year.
|
|
39
|
+
- **parseDate**: Parses a date string or Date object into a Date object.
|
|
40
|
+
- **parseTime**: Parses a time string into an object with hour, minute, and second properties.
|
|
41
|
+
- **parseTimeToString**: Parses a time string into a formatted string.
|
|
42
|
+
- **formatDateTime**: Formats a date string or Date object into a string with a specified format.
|
|
43
|
+
- **parseDateToString**: Parses a date string or Date object into a formatted string with the specified moment.js-style date format.
|
|
44
|
+
- **isDate**: Determines if a value is a valid date.
|
|
45
|
+
- **isDateInRange**: Determines if a date falls within a specified range (either past or future).
|
|
46
|
+
- **isTime**: Determines if a value is a valid time.
|
|
47
|
+
- **isEmail**: Determines if a value is a valid email address.
|
|
48
|
+
- **parseNANPTel**: Parses a North American phone number string into a standardized format.
|
|
49
|
+
- **isNANPTel**: Determines if a value is a valid North American phone number.
|
|
50
|
+
- **parseInteger**: Parses an integer string into a standardized format.
|
|
51
|
+
- **isNumber**: Determines if a value is a valid number.
|
|
52
|
+
- **parseNumber**: Parses a number string into a standardized format.
|
|
53
|
+
- **isInteger**: Determines if a value is a valid integer.
|
|
54
|
+
- **parseUrl**: Parses a URL string into a standardized format.
|
|
55
|
+
- **isUrl**: Determines if a value is a valid URL.
|
|
56
|
+
- **parseZip**: Parses a zip code string into a standardized format.
|
|
57
|
+
- **isZip**: Determines if a value is a valid zip code.
|
|
58
|
+
- **parsePostalCA**: Parses a Canadian postal code string into a standardized format.
|
|
59
|
+
- **isPostalCA**: Determines if a value is a valid Canadian postal code.
|
|
60
|
+
- **isColor**: Determines if a value is a valid color.
|
|
61
|
+
- **parseColor**: Parses a color string into a standardized format.
|
|
62
|
+
- **normalizeValidationResult**: Normalizes a validation result (like a boolean or string) into an object with a valid property and a messages array of strings.
|
|
63
|
+
|
|
64
|
+
## Contributing
|
|
65
|
+
|
|
66
|
+
Install dev dependencies:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm install
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
When running Vite, you may get an error like
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
Module did not self-register: '...\node_modules\canvas\build\Release\canvas.node'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If that happens, you
|
|
79
|
+
need to install the canvas module manually: `bash npm rebuild canvas --update-binary `
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(i,f){typeof exports=="object"&&typeof module<"u"?f(exports):typeof define=="function"&&define.amd?define(["exports"],f):(i=typeof globalThis<"u"?globalThis:i||self,f(i.validatorUtils={}))})(this,function(i){"use strict";function f(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function R(e,n){typeof n=="string"&&(n=[n]);const t=e.dataset.type||"",r=e.type;return!!(n.includes(t)||n.includes(r))}function T(e){return e.replace(/YYYY/g,"Y").replace(/YY/g,"y").replace(/MMMM/g,"F").replace(/MMM/g,"{3}").replace(/MM/g,"{2}").replace(/M/g,"n").replace(/DD/g,"{5}").replace(/D/g,"j").replace(/dddd/g,"l").replace(/ddd/g,"D").replace(/dd/g,"D").replace(/d/g,"w").replace(/HH/g,"{6}").replace(/H/g,"G").replace(/hh/g,"h").replace(/mm/g,"i").replace(/m/g,"i").replace(/ss/g,"S").replace(/s/g,"s").replace(/A/gi,"K").replace(/\{3\}/g,"M").replace(/\{2\}/g,"m").replace(/\{5\}/g,"d").replace(/\{6\}/g,"H")}function M(e){const n=parseInt(e);if(typeof e=="number"||!isNaN(n))return n-1;const t=new Date(`1 ${e} 2000`).getMonth();if(!isNaN(t))return t;const r={ja:0,en:0,fe:1,fé:1,ap:3,ab:3,av:3,mai:4,juin:5,juil:6,au:7,ag:7,ao:7,se:8,o:9,n:10,d:11};for(const l in r)if(e.toLowerCase().startsWith(l))return r[l];throw new Error("Invalid month name: "+e)}function y(e){return typeof e=="string"&&(e=parseInt(e.replace(/\D/g,""))),e>99?e:e<(new Date().getFullYear()+20)%100?e+2e3:e+1900}function m(e){if(e instanceof Date)return e;e=e.trim().toLowerCase();let n=0,t=0,r=0,l=0,s=0,a=0;const d=new RegExp(/\d{1,2}\:\d\d(?:\:\d\ds?)?\s?(?:[a|p]m?)?/gi);if(d.test(e)){const c=e.match(d)[0];e=e.replace(c,"").trim();const g=p(c);if(g!==null&&({hour:l,minute:s,second:a}=g),e.length<=2){const D=new Date;return new Date(D.getFullYear(),D.getMonth(),D.getDate(),l,s,a)}}const u=/(^|\b)(mo|tu|we|th|fr|sa|su|lu|mard|mer|jeu|ve|dom)[\w]*\.?/gi;e=e.replace(u,"").trim();const o=new Date(new Date().setHours(0,0,0,0));if(/(now|today)/.test(e))return o;if(e.includes("tomorrow"))return new Date(o.setDate(o.getDate()+1));e.length===8&&(e=e.replace(/(\d\d\d\d)(\d\d)(\d\d)/,"$1-$2-$3")),e.length===6&&(e=e.replace(/(\d\d)(\d\d)(\d\d)/,y(e.slice(0,2))+"-$2-$3"));try{({year:n,month:t,day:r}=S(e))}catch{return new Date("")}return new Date(n,t-1,r,l,s,a)}function N(e,n=[null,null,null]){const t=r=>r.filter(l=>!n.includes(l));return e===0||e>31?t(["y"]):e>12?t(["d","y"]):e>=1&&e<=12?t(["m","d","y"]):[]}function S(e){const n=e.split(/[\s-/:.,]+/).filter(s=>s!=="");if(n.length<3){if(e.match(/\d{4}/)!==null)throw new Error("Invalid Date");n.unshift(String(new Date().getFullYear()))}const t={year:0,month:0,day:0};function r(s,a){s==="year"?t.year=y(a):t[s]=a}let l=0;for(;!(t.year&&t.month&&t.day);){e:for(const s of n){if(l++,/^[a-zA-Zé]+$/.test(s)){t.month||r("month",M(s)+1);continue}if(/^'\d\d$/.test(s)||/^\d{3,5}$/.test(s)){t.year||r("year",parseInt(s.replace(/'/,"")));continue}const a=parseInt(s);if(isNaN(a))throw console.error(`not date because ${s} isNaN`),new Error("Invalid Date");const d=N(a,[t.year?"y":null,t.month?"m":null,t.day?"d":null]);if(d.length==1){if(d[0]==="m"&&!t.month){r("month",a);continue e}if(d[0]==="d"&&!t.day){r("day",a);continue e}if(d[0]==="y"&&!t.year){r("year",a);continue e}}l>3&&(!t.month&&d.includes("m")?r("month",a):!t.day&&d.includes("d")&&r("day",a))}if(l>6)throw new Error("Invalid Date")}if(t.year&&t.month&&t.day)return t;throw new Error("Invalid Date")}function p(e){if(e=e.trim().toLowerCase(),e==="now"){const o=new Date;return{hour:o.getHours(),minute:o.getMinutes(),second:o.getSeconds()}}const n=e.match(/(\d{3,4})/);if(n){const o=n[1].length,c=n[1].slice(0,o==3?1:2),g=n[1].slice(-2);e=e.replace(n[1],c+":"+g)}const t=new RegExp(/^(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)m?)?$/i);if(t.test(e)){const o=e.match(t);if(o===null)return null;e=o[1]+":"+(o[2]||"00")+(o[3]||"")}const r=new RegExp(/^(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?\s*(?:(a|p)m?)?$/i);if(!r.test(e))return null;const l=e.match(r);if(l===null)return null;const s=parseInt(l[1]),a=parseInt(l[2]),d=l[3]?parseInt(l[3]):0,u=l[4];return isNaN(s)||isNaN(a)||isNaN(d)?null:u==="p"&&s<12?{hour:s+12,minute:a,second:d}:u==="a"&&s===12?{hour:0,minute:a,second:d}:s<0||s>23||a<0||a>59||d<0||d>59?null:{hour:s,minute:a,second:d}}function k(e,n="h:mm A"){const t=p(e);if(t){const r=new Date;return r.setHours(t.hour),r.setMinutes(t.minute),r.setSeconds(t.second),r.setMilliseconds(0),w(r,n)}return""}function w(e,n="YYYY-MM-DD"){if(e=m(e),isNaN(e.getTime()))return"";const t={y:e.getFullYear(),M:e.getMonth(),D:e.getDate(),W:e.getDay(),H:e.getHours(),m:e.getMinutes(),s:e.getSeconds(),ms:e.getMilliseconds()},r=(o,c=2)=>(o+"").padStart(c,"0"),l=()=>t.H%12||12,s=o=>o<12?"AM":"PM",a=o=>"January|February|March|April|May|June|July|August|September|October|November|December".split("|")[o];function d(o,c=0){const g="Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday".split("|");return c?g[o].slice(0,c):g[o]}const u={YY:String(t.y).slice(-2),YYYY:t.y,M:t.M+1,MM:r(t.M+1),MMMM:a(t.M),MMM:a(t.M).slice(0,3),D:String(t.D),DD:r(t.D),d:String(t.W),dd:d(t.W,2),ddd:d(t.W,3),dddd:d(t.W),H:String(t.H),HH:r(t.H),h:l(),hh:r(l()),A:s(t.H),a:s(t.H).toLowerCase(),m:String(t.m),mm:r(t.m),s:String(t.s),ss:r(t.s),SSS:r(t.ms,3)};return n.replace(/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,(o,c)=>c||u[o])}function $(e,n){const t=m(e);return isNaN(t.getTime())?"":((!n||n.length===0)&&(n="YYYY-MMM-DD"),w(t,n))}function x(e){if(typeof e!="string"&&!(e instanceof Date))return!1;let n=m(e);return n==null?!1:!isNaN(n.getTime())}function A(e,n){return!(n==="past"&&e>new Date||n==="future"&&e.getTime()<new Date().setHours(0,0,0,0))}function E(e){let n=p(e);return n===null?!1:!isNaN(n.hour)&&!isNaN(n.minute)&&!isNaN(n.second)}function C(e){if(e.length>255||!new RegExp(/^.+@.+\.[a-zA-Z0-9]{2,}$/).test(e))return!1;let t="";return t+="^([a-zA-Z0-9!#$%'*+/=?^_`{|}~-]+",t+="(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*",t+="|",t+='"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*"',t+=")@(",t+="(",t+="(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+",t+="[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?",t+=")",t+=")$",new RegExp(t).test(e)}function Y(e){return e=e.replace(/^[^2-90]+/g,""),e=e.replace(/(\d\d\d).*?(\d\d\d).*?(\d\d\d\d)(.*)/,"$1-$2-$3$4"),e}function H(e){return/^\d\d\d-\d\d\d-\d\d\d\d$/.test(e)}function P(e){return e.replace(/[^0-9]/g,"")}function I(e){return/^\-?\d*\.?\d*$/.test(e)}function Z(e){return e.replace(/[^\-0-9.]/g,"").replace(/(^-)|(-)/g,(n,t)=>t?"-":"").replace(/(\..*)\./g,"$1")}function z(e){return/^\-?\d*$/.test(e)}function F(e){return e=e.trim(),new RegExp("^(?:[a-z+]+:)?//","i").test(e)?e:"https://"+e}function L(e){return new RegExp("^(?:[-a-z+]+:)?//","i").test(e)}function j(e){return e=e.replace(/[^0-9]/g,"").replace(/(.{5})(.*)/,"$1-$2").trim(),e.length===6&&(e=e.replace(/-/,"")),e}function q(e){return new RegExp(/^\d{5}(-\d{4})?$/).test(e)}function W(e){return e=e.toUpperCase().replace(/[^A-Z0-9]/g,"").replace(/(.{3})\s*(.*)/,"$1 $2").trim(),e}function J(e){return new RegExp(/^[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ] ?[0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]$/).test(e)}function U(e){return["transparent","currentColor"].includes(e)?!0:typeof e!="string"||!e.trim()?!1:typeof CSS=="object"&&typeof CSS.supports=="function"?CSS.supports("color",e):V(e)}function V(e){const n=new RegExp(/^rgba?\(\s*(\d{1,3}%?,\s*){2}\d{1,3}%?\s*(?:,\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),t=new RegExp(/^hsla?\(\s*\d+(deg|grad|rad|turn)?,\s*\d{1,3}%,\s*\s*\d{1,3}%(?:,\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),r=new RegExp(/^rgba?\(\s*(\d{1,3}%?\s+){2}\d{1,3}%?\s*(?:\s*\/\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),l=new RegExp(/^hsla?\(\s*\d+(deg|grad|rad|turn)?\s+\d{1,3}%\s+\s*\d{1,3}%(?:\s*\/\s*(\.\d+|0+(\.\d+)?|1(\.0+)?|0|1\.0|\d{1,2}(\.\d*)?%|100%))?\s*\)$/),s=new RegExp(/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i);let a="aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|rebeccapurple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen";const d=new RegExp(`^(${a})$`,"i");return n.test(e)||t.test(e)||r.test(e)||l.test(e)||s.test(e)||d.test(e)}let h=null;const b=new Map;function G(e){if(e=e.trim().toLowerCase(),["transparent","currentcolor"].includes(e))return e;if(b.has(e))return b.get(e);h===null&&(h=document.createElement("canvas"),h.willReadFrequently=!0);let n=h.getContext("2d");if(!n)throw new Error("Can't get context from colorCanvas");n.fillStyle=e,n.fillRect(0,0,1,1);let t=n.getImageData(0,0,1,1).data,r="#"+("000000"+(t[0]<<16|t[1]<<8|t[2]).toString(16)).slice(-6);return b.set(e,r),r}function K(e){let n={valid:!1,error:!1,messages:[]};return typeof e=="boolean"?{valid:e,error:!1,messages:[]}:typeof e=="string"?{valid:!1,error:!1,messages:[e]}:(typeof e.valid=="boolean"&&(n.valid=e.valid),typeof e.message=="string"&&(n.messages=[e.message]),typeof e.messages=="string"&&(n.messages=[e.messages]),Array.isArray(e.messages)&&(n.messages=e.messages),e.error===!0&&(n.error=!0),n)}i.formatDateTime=w,i.isColor=U,i.isDate=x,i.isDateInRange=A,i.isEmail=C,i.isFormControl=f,i.isInteger=z,i.isNANPTel=H,i.isNumber=I,i.isPostalCA=J,i.isTime=E,i.isType=R,i.isUrl=L,i.isZip=q,i.momentToFPFormat=T,i.monthToNumber=M,i.normalizeValidationResult=K,i.parseColor=G,i.parseDate=m,i.parseDateToString=$,i.parseInteger=P,i.parseNANPTel=Y,i.parseNumber=Z,i.parsePostalCA=W,i.parseTime=p,i.parseTimeToString=k,i.parseUrl=F,i.parseZip=j,i.yearToFull=y,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jdlien/validator-utils",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"module": "dist/validator-utils.js",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"description": "Validation and sanitization functions used by @jdlien/Validator.",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "vite",
|
|
12
|
+
"build": "tsc && vite build",
|
|
13
|
+
"preview": "vite preview",
|
|
14
|
+
"test": "vitest",
|
|
15
|
+
"coverage": "vitest --coverage"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/jdlien/validator-utils.git"
|
|
20
|
+
},
|
|
21
|
+
"publishConfig": {
|
|
22
|
+
"access": "public"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"validation",
|
|
26
|
+
"utilties",
|
|
27
|
+
"sanitization",
|
|
28
|
+
"date",
|
|
29
|
+
"time",
|
|
30
|
+
"color"
|
|
31
|
+
],
|
|
32
|
+
"author": "JD Lien",
|
|
33
|
+
"license": "ISC",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/jdlien/validator-utils/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/jdlien/validator-utils#readme",
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/jsdom": "^21.1.0",
|
|
40
|
+
"@vitest/coverage-c8": "^0.28.5",
|
|
41
|
+
"canvas": "^2.11.0",
|
|
42
|
+
"jsdom": "^21.1.0",
|
|
43
|
+
"jsdom-global": "^3.0.2",
|
|
44
|
+
"prettier": "^2.8.4",
|
|
45
|
+
"typescript": "^4.9.3",
|
|
46
|
+
"vite": "^4.1.0",
|
|
47
|
+
"vitest": "^0.28.5"
|
|
48
|
+
},
|
|
49
|
+
"sideEffects": false
|
|
50
|
+
}
|