datum-focus
Version:
Data shape, model, metadata, JSON, JSON Schema, GraphQL, MongoDB query and aggregations, iterator generators
124 lines (108 loc) • 3.47 kB
text/typescript
export type AbsoluteUrl = string;
export type Base64 = string;
export type Base64Url = string;
export type Code = string;
export type EmailAddress = string;
export type Guid = string;
export type LowerCase = string;
export type Json = Code;
export type NumberLike = string;
export type PhoneNumber = string;
export type UpperCase = string;
export const DATE_STR = "date";
export const EMAIL = "email";
export const GUID = "guid";
export const NAME = "name";
export const PASSWORD = "password";
export const REGEX = "regex";
export const STRING = "string";
export const URL = "url";
export const USERNAME = "username";
export const STRING_TYPES = [
DATE_STR,
EMAIL,
GUID,
NAME,
PASSWORD,
REGEX,
STRING,
URL,
USERNAME,
] as const;
export type StringType = typeof STRING_TYPES[number];
const EMAIL_EX = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
const GUID_EX = /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/;
const PHONE_EX = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im;
const URL_EX = /^[a-z][a-z0-9+.-]*:/;
export const isAbsoluteUrl = (val: unknown): val is AbsoluteUrl =>
isString(val) && URL_EX.test(val);
export const isEmailAddress = (val: unknown): val is EmailAddress =>
isString(val) && EMAIL_EX.test(val);
export const isGuid = (val: unknown): val is Guid =>
isString(val) && GUID_EX.test(val);
export const isIntegerLike = (val: unknown): val is number =>
isString(val) && val == String(parseInt(val));
export const isLowerCase = (val: unknown): val is LowerCase =>
isString(val) && val === val.toLowerCase();
export const isNumberLike = (val: unknown): val is NumberLike =>
isString(val) && val == String(parseFloat(val));
/*
(123) 456-7890
(123)456-7890
123-456-7890
123.456.7890
1234567890
+31636363634
075-63546725
*/
export const isAlphaNumeric = (val: unknown): val is String => {
const regExp = /^[A-Za-z0-9]+$/;
return isString(val) && !!val.match(regExp);
};
export const isPhoneNumber = (val: unknown): val is PhoneNumber =>
isString(val) && PHONE_EX.test(val);
export const isString = (val: unknown): val is string => typeof val === STRING;
export const isUpperCase = (val: unknown): val is UpperCase =>
isString(val) && val === val.toUpperCase();
export const isValidJSON = (val: unknown): val is Json => {
if (!isString(val)) {
return false;
}
try {
JSON.parse(val);
return true;
} catch (e) {
return false;
}
};
/**
* http://crockford.com/javascript/
* alert(supplant("I'm {age} years old!", { age: 29 }));
* alert(supplant("The {a} says {n}, {n}, {n}!", { a: 'cow', n: 'moo' }));
* @param template
* @param obj
* @returns
*/
export const supplant = (template: string, obj: Record<string, any>) => {
return template.replace(/{([^{}]*)}/g, // (substring: string, ...args: any[])
(substring: string, key: any): string => {
const val = obj[key];
switch (typeof val) {
case 'string':
return val;
case 'number':
return String(val);
case 'bigint':
return String(val);
case 'boolean':
return String(val);
case 'function':
return String(val.bind(obj)());
case 'object':
return val === null ? '' : JSON.stringify(val);
default:
return substring;
}
}
);
};