@fishertsau/moonlight
v1.27.16
Published
Various helpers or lib for javascript projects
Downloads
1,285
Readme
moonlight
- 提供JavaScript常用的功能,類似helper或是utility,讓javascript專案使用
- 可用於Server-side專案,如node.js,或是Client-side專案,如vue,react中
- 發佈於npm中,使用時當作一個package使用
- 可用於es6與commonjs中
Main functions
- Validator
- time
- array
- hostname
- Checker
- Utils
- MoonUse
- Model
Input Validator
check the input validity with specified rules
only the validated attribute(s) are returned
convert data type on validating, e.g '100' to 100 for 'type:number'
rules
- required
- type:[string|date|datetime|isoDatetime|number|email|bool|boolean|null|nonEmptyString|object]
- same:attributeName
validator:: obj -> obj -> obj
examples
const rules = { foo: 'required|type:null', // null boo: 'type:bool', // true, false, 'true', 'false' boo: 'type:boolean', // true, false, 'true', 'false' // string moo: 'type:string', // string moo: 'required|type:emptyString', // '' moo: 'required|type:nonEmptyString', // non empty string moo: 'required|type:lowerCaseOrNumberString', // lower case or number string (e.g. 'abc123') moo: 'required|type:isNumberString', // number string (e.g. '123') // object boo: 'type:object', // object boo: 'type:emptyObject', // {} // same content bar: 'required|same:foo', // valid values loo: 'validValues:[v1,v2,v3]', aoo: 'type:array', // array aoo: 'type:emptyArray', // [] aoo: 'type:arrayOfString', // ['a','b'] aoo: 'type:arrayOfInt', // [1,2] aoo: 'type:arrayOfNull', // [null, null] // multiple types soo: 'type:[number,null,nonEmptyString]', // number, null, non empty string // number & integer foo: 'required|type:number', // number (e.g. 1.2) aoo: 'type:int', // integer (e.g. 1) aoo: 'type:positiveInt', // > 0 // date & datetime too: 'type:datetime', // yyyy-mm-dd hh:mm:ss (e.g. '2000-01-01 12:00:00') too: 'type:isoDatetime', // yyyy-mm-ddThh:mm:ss+08:00 (e.g. '2000-01-01T12:00:00+08:00') too: 'type:date', // yyyy-mm-dd (e.g. '2000-01-01') too: 'type:yearMonthDay', // {year:1, month: 1, day: 1} // length: same length foo: 'sameLengthArr:bar', // same length as bar (e.g. '123' and 'abc') foo: 'minLen:3', // min length (e.g. '123') foo: 'maxLen:5', // max length (e.g. '12345') // range foo: 'range:1,10', // 1 <= foo <= 10 (for int only) // requiredWhenExists foo: 'requiredWhenExists:boo', // required when boo is not empty (e.g. 'foo' is required when 'boo' is not empty) foo: 'requiredIfValueIs:bar:1', // required when bar is 1 (e.g. 'foo' is required when 'bar' is 1) // requiredIfValueIs foo: 'requiredIfValueIs:bar:true', // required when bar is true (e.g. 'foo' is required when 'bar' is 1) foo: 'requiredIfValueIs:bar:10', // required when bar is 10 (e.g. 'foo' is required when 'bar' is 10) // app types koo: 'type:email', // email koo: 'type:hostname', // hostname (e.g. 'www.google.com') koo: 'type:hostnameWithPath', // hostname with path (e.g. 'www.google.com/path') koo: 'type:lineId', // line id (e.g. 'U1234567890abcdef1234567890abcdef') koo: 'type:twTaxId', // Taiwan tax id (8 digits) (e.g. '12345678') koo: 'type:twMobileNo', // Taiwan mobile number (10 digits) (e.g. '0912345678') koo: 'type:twLandPhoneNo', // Taiwan land phone number (9 digits) (e.g. '022345678') koo: 'type:addressWithDefault', // address with default value (e.g. {city:1, area:1, street:'abc'}) }; const validatedData = { foo: 123, bar: 123, koo: '2000-01-01', loo: 'invalidValue', moo: '', aoo:'notArray'}; let result = validator(rules)(validatedData); // => { validated: true , values:{foo:123, bar:123,koo:'2000-01-01'}} // => { validated: false , // errors: { // foo: ['foo should be a number.'], // koo: ['koo should be a string.'] // loo: ['loo should be in one of the values: v1,v2,v3.'] // moo: ['moo should be an non empty string.'] // aoo: ['aoo should be in array format.'] // } // }
time
now :: null -> DateTime
now(); //=> current time
isoStrToUtcStr:: isoDatetimeString -> utcDatetimeString
isoStrToUtcStr('1997-07-16T19:20:35+03:00'); //=> '1997-07-16 16:20:35'
isoStrToTaipeiStr :: isoDatetimeString -> taipeiDatetimeString
isoStrToTaipeiStr('1997-07-16T19:20:35+03:00'); // utc: 1997-07-16T16:20:35 //=> '1997-07-17 00:20:35'
{
// base
Dayjs,
now,
// string to object
toTimeObj,
fromIsoTimeStrToObj,
fromTimeStrAtTZ,
fromTpeTimeStr,
// datetime string
utcDatetimeStrNow, // 2000-01-01 12:00:00
isoStrNow,
// string to string
isoStrToUtcStr, // 2000-01-01T12:00:00.000Z -> 2000-01-01 12:00:00
utcStrToIsoStr,
isoStrToTaipeiStr, // 2000-01-01T12:00:00.000Z -> 2000-01-01 20:00:00
datetimeStrToDateStr, // 2000-01-01 12:00:00 -> 2000-01-01
isoStrToTpeDateStr, // 2000-01-01T12:00:00.000Z -> 2000-01-01
// date|datetime string
dateAtTZ,
todayStartInTpeStr,
todayEndInTpeStr,
todayEndInIsoStr,
todayInTpeStrDateOnly,
// time obj
todayStartInTpe,
todayEndInTpe,
// type check
isIsoFormat,
// time zone
TZ,
TZ_TYPE,
// comparison
isBefore,
isAfter,
isBetween,
isSame,
// duration
getDuration,
// status
getStatusByTimeFrame,
STATUS_BY_TIME_FRAME,
REF_TIME_STATUS_TYPE,
// time manipulation
minAgoFromNow
}
array
- shuffle :: array -> array
- re-order the array items randomly
hostname
- isValidHostname :: String -> Boolean
- To validate a give hostname
Checker
isTrue,
isEmpty,
isValidBool,
isFunction,
isUndefined,
// object
isObject,
isEmptyObject,
// string
isString,
isNonEmptyString,
isNumberString,
isEmptyString,
isLowerCaseOrNumberString,
isNumberOrString,
isNumberOrNumberString,
// number
isIntBetween,
isNumber,
isValidInteger,
isPositiveInteger,
isUnsignedInteger,
isSameNumOrNumStr,
// number format
ifOnlyNumberAndLetter,
ifHexNumberStr,
ifDecimalNumberStr,
// time
isYMDStr,
isDatetimeStr,
isIsoFormat,
isIsoFormatWithZeroOffset,
// array
isArray,
isEmptyArray,
isNonEmptyArray,
isArrayOfString,
isArrayOfInt,
isArrayOfArray, // [[], []]
isArrayOfNumber,
isArrayOfNull,
// application
isValidLineId,
isValidEmail,
isValidTwTaxId,
isValidTwMobileNo,
isValidTwLandPhoneNo,
isValidTwNationalId,
isValidHostname,
isValidHostnameWithPath,
isTrue :: a -> boolean
- To check if a given value is true
isEmpty :: a -> boolean
- To check is a given value is empty
isIntBetween:: int a -> int b -> int c -> boolean
- To check is a given int or value is between the specified range
isNumber:: a -> boolean
- To check is given value is a number
isString:: a -> boolean
- To check is given value is a string
isObject:: a -> boolean
- To check is given value is an object
- null and array are excluded
isValidEmail:: a -> boolean
- To check is given value is a valid email
isValidBool:: a -> boolean
- To check is given value is a valid boolean value
isFunction:: a -> boolean
- To check is given value a Function
isValidHostname:: a -> boolean
- To check if a given value a valid hostname
isYMDStr:: str a -> boolean
- To check is given string is in date format
- valid date format: yyyy-mm-dd (time is not included)
isDateTime:: str a -> boolean
- To check is given string is in datetime format
- valid datetime format includes: unix time (integer), date+time, UTC
isIsoFormat:: a -> boolean
- To check is given value is in ISO 8601 format
isIsoFormatWithZeroOffset:: a -> boolean
- To check is given value is in ISO 8601 format with zero offset
Utils
clearSpace:: string -> string
- To clear or remove space in a string
trim
- To trim the string(s) in object properties and values
- To trim string(s) in list
- Can trim string(s) in nested objects or nested array
trim({ 'p1 ': 'foo ', p2: [' abc', ' def '], p3: { p3_1: ['p31 '] }, p4: { p4_1: ['p41 ', ' p42'], 'p4_2': {} }, p5: 100, }); //=> { p1: 'foo', p2: ['abc', 'def'], p3: { p3_1: ['p31'] }, p4: { p4_1: ['p41', 'p42'], 'p4_2' : {} }, p5: 100, }
extractByPath
To extract a value from a structured collection object
Object structure
{ k1: { k1a: {} k1b: {} }, k2: { k2a: {} k2b: {} } }
example:
extractByPath(['info', 'age'])({'person1':{info:{age:10}}, 'person2':{info:{age:20}}}); //=> {'person1':10, 'person2':20}
getDirty
To get the values in new object which differ from that in the original object
The function is auto-curry
example:
oriObj = {a:1, b:3} newObj = {a:1, b:5, c:7} getDirty(oriObj)(newObj); //=> {b:5, c:7}
renameKey
To change a key name
example:
oriObj = {foo:1} renameKey('foo','bar')(oriObj); //=> {bar:1}
createEventEmitter
To create an event emitter
example:
const em = createEventEmitter(); // register event handler em.on('someEvent', someHandler); // remove event handler // A. remove specific handler em.remove('someEvent', someHandler); // B. remove all handlers em.remove('someEvent'); // send out event em.emit('someEvent', payload);
pluckObjProp
To pluck a nested obj prop
example:
// Functor f => k -> {k:v} -> {k:v} const obj = { prop1: { foo: 123, bar: 'abc' }, prop2: { foo: 999, bar: 'abc' } } pluckObjProp('foo')(obj) //=> {prop1: 123, prop2: 999}
clean
- To remove obj props if value is undefined/null/emptyString
- Applicable to nested object
clean({ foo: 123, bar: undefined, koo: { k1: 'abc', k2: undefined, }, poo: null, moo: '', }) //=> { foo: 123, koo: { k1:'abc'} }
cleanNilUndefined
- To remove obj props if value is undefined/null
- Applicable to nested object
clean({ foo: 123, bar: undefined, koo: { k1: 'abc', k2: undefined, }, poo: null, moo: '', }) //=> { foo: 123, koo: { k1:'abc'} moo: '' }
hasValue
- To check if an object has specified value
- Applicable to simple object
hasValue(123, { foo: 123 }) //=> true hasValue('abc', { foo: 123 }) //=> false
rmArrSquareInReqParamsKey
harmArrSquareInReqParamsKeys( { from: 0, 'ids[]': [ 'abc1705548556993', 'abc1705558802725'] }); //=> { from: 0, 'ids': [ 'abc1705548556993' , 'abc1705558802725'] };
getObjectDifference
const obj1 = {
a: 1,
b: {
c: 2,
d: {
e: 3,
},
},
f: {
g: 5,
},
};
const obj2 = {
a: 1,
b: {
c: 3,
d: {
e: 4,
},
},
};
getObjectDifference(obj1, obj2);
//=>
{
{
'b.c'
:
[2, 3], 'b.d.e';
:
[3, 4], f;
:
[{ g: 5 }, undefined];
}
parseObj :: obj -> QueryString
- convert an object to query string
- example:
parsrStr({a:'foo',b:'bar'}) //=> a=foo&b=bar
parseStr :: QueryString -> obj
- convert a query string to an object
- example:
parsrObj('a=foo&b=bar') //=> {a:'foo',b:'bar'}
convertKeyValue :: [a] -> obj (a: 'str=str')
- convert a key-value array to an object
convertKeyValue(['foo=bar', 'fiz=fuz']); //=> {foo:'bar', fiz:'fuz'}
convertObjToArr :: obj -> [a] (a: 'str=str')
- convert an object to a key-value array
convertKeyValue({ foo: 'bar', fiz: 'fuz' }); //=> ['foo=bar', 'fiz=fuz']
snakeToCamel :: str -> str
- convert a snake-string to camel-case string
snakeToCamel('abc_def_ghi') //=> 'abcDefGhi'
objKeyToCamel :: obj -> obj
- convert all keys in an object from snake to camel string
- nested object is supported
objKeyToCamel({this_is_key: val}) //=> {thisIsKey: val}
camelToSnake :: str -> str
- convert a camel-case string to snake-case string
camelToSnake('abcDefGhi') //=> 'abc_def_ghi'
objKeyToSnake :: obj -> obj
- convert all keys in an object from camel to snake-case string
- nested object is supported
objKeyToSnake({ thisIsKey: 'someVal' }) //=> { this_is_key: 'someVal' }
parseCookie :: string -> obj
- parse a cookie string to an object
parseCookie('foo=bar ; equation=E%3Dmc%5E2; asd='); //=> { foo: 'bar', equation: 'E=mc^2', asd: '' }
serializeCookie :: obj -> string
- serialize an object to cookie string
serializeCookie({ foo: 'bar', equation: 'E=mc^2', asd: '' }); //=> 'foo=bar;equation=E%3Dmc%5E2;asd='
MoonUse
useRetry
useLock
useWait
- To make an action execution wait for a given time before execution
useWait(1000, action); //=> wait for 1000ms, and then run action - ```
useRedisCache
- To get value from redis cache, otherwise get the value and cache it
const foo = await useCache('someCacheKey', getter, {keyLife:100}); //=> keyLife: key有效時間 (in second) - ```
Model
- basicTypes
YES_NO_TYPE,
NULLABLE_YES_NO_TYPE,
STRING_TYPE,
NON_EMPTY_STRING_TYPE,
NUMBER_OR_STRING_TYPE,
NULLABLE_STRING_TYPE,
INTEGER_TYPE,
UNSIGNED_INTEGER_TYPE,
NULLABLE_INTEGER_TYPE,
POSITIVE_INTEGER_TYPE,
NULLABLE_UNSIGNED_INTEGER_TYPE,
BIG_INTEGER_TYPE,
NULLABLE_BIG_INTEGER_TYPE,
UNSIGNED_TINY_INTEGER_TYPE,
NUMBER_TYPE,
ARRAY_TYPE,
ARRAY_OF_INT_TYPE,
NULLABLE_ARRAY_TYPE,
OBJECT_TYPE,
NULLABLE_OBJECT_TYPE,
FUNCTION_TYPE,
NULLABLE_FUNCTION_TYPE,
- example
```
Model.basicTypes.STRING_TYPE;
```
- datetimeTypes
DATE_TYPE,
NULLABLE_DATE_TYPE,
DATETIME_TYPE,
NULLABLE_DATETIME_TYPE,
ISO_DATETIME_TYPE,
NULLABLE_ISO_DATETIME_TYPE,
- appTypes
EMAIL_TYPE,
NULLABLE_EMAIL_TYPE,
EMPTY_STRING_OR_EMAIL_TYPE,
LINE_ID_TYPE,
EMPTY_STRING_OR_LINE_ID_TYPE,
CITY_TYPE,
CITY_AREA_TYPE,
MEDIA_TYPE,
TW_TAX_ID_TYPE,
NULLABLE_TW_TAX_ID_TYPE,
TW_MOBILE_NO_TYPE,
HOSTNAME_TYPE,
NULLABLE_HOSTNAME_TYPE,
EMPTY_STRING_OR_HOSTNAME_TYPE,
appTypes.CITY_TYPE (台灣城市)
結構: 整數 (城市編號)
properties:
- validator
- cityList (台灣城市清單)
會檢查縣市是否為合法值
appTypes.CITY_AREA_TYPE (台灣城市與區域)
結構:
{cityId: 1, areaId: 1}
properties:
- validator
- cityList (台灣城市清單)
- areaList (台灣區域清單,含城市編號與區域號碼)
會檢查縣市與區域的對應,是否為合法值
城市與區域未定: {cityId:0, areaId:0}
使用範例
const someModelDef = { location: { type: CITY_AREA_TYPE, } }
cityList內容
const cityList = [
{ id: 0, name: '未定義' },
{ id: 1, name: '台北市' },
...
];
- areaList內容
const areaList = [
{ id: 0, cityId: 0, name: '未定義', zip: 0 },
{ id: 1, cityId: 1, name: '中正區', zip: 100 },
...
];