New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@cpmech/basic

Package Overview
Dependencies
Maintainers
1
Versions
105
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cpmech/basic - npm Package Compare versions

Comparing version 4.6.0 to 4.7.0

418

dist/cjs/index.js

@@ -1,1 +0,417 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e=e=>""!==e&&"null"!==e,t=(e,o="__EMPTY__",r=!1)=>Object.keys(e).reduce((s,i)=>({...s,[i]:null===e[i]||void 0===e[i]?r?e[i]:o:Array.isArray(e[i])?e[i].map(e=>""===e?o:e):"object"==typeof e[i]?t(e[i],o):""===e[i]?o:e[i]}),{}),o=e=>Object.keys(e).reduce((t,r)=>({...t,[r]:Array.isArray(e[r])?e[r].slice(0):"object"==typeof e[r]?o(e[r]):e[r]}),{}),r=(e,t)=>{const o=Object.keys(e);for(const s of o){const o=t[s];Array.isArray(o)?e[s]=o.slice(0):"object"==typeof o?r(e[s],o):e[s]=o}},s=(e,t)=>{if(e.length!==t.length)return!1;for(let o=0;o<e.length;o++)if(e[o]!==t[o])return!1;return!0},i=(e,t)=>{const o=Object.keys(e);for(const r of o){const o=t[r];if(Array.isArray(o)){if(!s(e[r],o))return!0}else if("object"==typeof e[r]&&null!==e[r]){if(i(e[r],o))return!0}else if(e[r]!==o)return!0}return!1},n=(e,t="__EMPTY__",o=!1)=>Object.keys(e).reduce((r,s)=>({...r,[s]:null===e[s]||void 0===e[s]?o?e[s]:"":Array.isArray(e[s])?e[s].map(e=>e===t?"":e):"object"==typeof e[s]?n(e[s],t):e[s]===t?"":e[s]}),{}),l=(e,t=!0)=>{const o=[];for(const r of Object.keys(e)){const s=e[r];o.push(r),"object"!=typeof s||Array.isArray(s)||(t&&o.push("{"),l(s,t).forEach(e=>o.push(e)),t&&o.push("}"))}return o},c=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);let p=!0,a=!0,y="[ERROR]";const u=(e,t)=>{for(const o of Object.keys(e))if(c(t,o)){const r=t[o];null!=r&&(Array.isArray(r)?e[o]=r.slice(0):"object"==typeof r?u(e[o],r):e[o]=r)}};exports.Locales=class{constructor(e,t="en",o="us"){this.getLocale=()=>this.locale,this.setLocale=e=>this.locale=e,this.getCountry=()=>this.country,this.setCountry=e=>this.country=e,this.getIndexDay=()=>"us"===this.country?1:0,this.getIndexMonth=()=>"us"===this.country?0:1,this.getFirstFieldMax=()=>"us"===this.country?12:31,this.getSecondFieldMax=()=>"us"===this.country?31:12,this.getDateFormat=()=>"us"===this.country?"MM/DD/YYYY":"DD/MM/YYYY",this.translate=(e,t="")=>{if(!c(this.resources,this.locale))return`INTERNAL_ERROR: cannot find locale ${this.locale} in resources object`;const o=this.resources[this.locale];if(!e)return"INTERNAL_ERROR: path variable must not be empty";const r=e.split(".").reduce((e,t)=>c(e,t)?e[t]:"",o);return r||(t||`INTERNAL_ERROR: cannot find message with path = ${e}`)},this.resources=e,this.locale=t,this.country=o}},exports.allFilled=(t,o)=>{let r;r=o?Object.keys(t).filter(e=>!o.includes(e)):Object.keys(t);for(const o of r)if(!e(t[o]))return!1;return!0},exports.blank2empty=t,exports.camelize=(e,t=!1,o="_")=>t?e.split(o).map(e=>e.toLowerCase().replace(/./,e=>e.toUpperCase())).join(""):e.split(o).map((e,t)=>t>0?e.toLowerCase().replace(/./,e=>e.toUpperCase()):e.toLowerCase()).join(""),exports.cloneSimple=o,exports.copySimple=r,exports.diffSimple=i,exports.elog=e=>{let t="";return e.message&&"string"==typeof e.message?(e.message.replace(`${y} `,""),t=`${y} ${e.message}`):t="string"==typeof e||"number"==typeof e||"boolean"==typeof e?`${y} ${e}`:`${y}\n${JSON.stringify(e,void 0,2)}`,t=t.replace(`${y} ${y}`,y),a&&console.log(t),t},exports.email2key=e=>e.toLowerCase().replace(/[@\.]/g,"_"),exports.empty2blank=n,exports.filled=e,exports.getObjectKeys=l,exports.hasProp=c,exports.limitNumDecimals=(e,t=2)=>Number(Number.parseFloat(String(e)).toFixed(t)),exports.makeGetField=(e,t)=>o=>{if(!Object.prototype.hasOwnProperty.call(e,o))throw new Error(`cannot find ${o}`);const r=e[o];if(typeof r!==t)throw new Error(`type of ${o} is incorrect`);return r},exports.makeSetField=(e,t,o)=>(r,s)=>{if(!Object.prototype.hasOwnProperty.call(e,r))throw new Error(`cannot find ${r}`);const i=e[r];if(typeof i!==o)throw new Error(`type of ${r} is incorrect`);i!==s&&(e[r]=s,t())},exports.maybeCopySimple=u,exports.mlog=e=>{p&&("string"==typeof e||"number"==typeof e||"boolean"==typeof e?console.log(e):console.log(JSON.stringify(e,void 0,2)))},exports.numOnly=e=>e.replace(/[\D\s\._\-]+/g,""),exports.setElog=e=>a=e,exports.setElogPrefix=e=>y=e,exports.setMlog=e=>p=e,exports.shallowCompareArrays=s,exports.sleep=e=>new Promise(t=>setTimeout(t,e)),exports.unixTimeNow=()=>Math.floor(Date.now()/1e3);
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const filled = (entry) => {
if (entry === '' || entry === 'null') {
return false;
}
return true;
};
// allFilled checks if all 'root-level' properties of object are filled (not '', not 'null')
const allFilled = (obj, ignoredKeys) => {
let keys;
if (ignoredKeys) {
keys = Object.keys(obj).filter(key => !ignoredKeys.includes(key));
}
else {
keys = Object.keys(obj);
}
for (const key of keys) {
if (!filled(obj[key])) {
return false;
}
}
return true;
};
// blank2empty will replace '' with empty recursively on SIMPLE objects
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
// (5) null or undefined will be converted to EMPTY
const blank2empty = (obj, empty = '__EMPTY__', keepUndefined = false) => Object.keys(obj).reduce((acc, curr) => ({
...acc,
[curr]: obj[curr] === null || obj[curr] === undefined
? keepUndefined
? obj[curr]
: empty
: Array.isArray(obj[curr])
? obj[curr].map((x) => (x === '' ? empty : x))
: typeof obj[curr] === 'object'
? blank2empty(obj[curr], empty)
: obj[curr] === ''
? empty
: obj[curr],
}), {});
const camelize = (name, firstUpper = false, separator = '_') => {
if (firstUpper) {
return name
.split(separator)
.map(w => w.toLowerCase().replace(/./, m => m.toUpperCase()))
.join('');
}
return name
.split(separator)
.map((w, i) => {
if (i > 0) {
return w.toLowerCase().replace(/./, m => m.toUpperCase());
}
return w.toLowerCase();
})
.join('');
};
// cloneSimple (hierarchically) creates a copy of "simple" entries of object
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
const cloneSimple = (obj) => Object.keys(obj).reduce((acc, curr) => ({
...acc,
[curr]: Array.isArray(obj[curr])
? obj[curr].slice(0)
: typeof obj[curr] === 'object'
? cloneSimple(obj[curr])
: obj[curr],
}), {});
// copySimple (hierarchically) copies all entries of object into destination
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
const copySimple = (destination, origin) => {
const keys = Object.keys(destination);
for (const key of keys) {
const value = origin[key];
if (Array.isArray(value)) {
destination[key] = value.slice(0);
}
else if (typeof value === 'object') {
copySimple(destination[key], value);
}
else {
destination[key] = value;
}
}
};
// shallowCompareArrays returns true if two arrays are equal to each other
// NOTE: the type of the array entries must be "fundamental"
const shallowCompareArrays = (left, right) => {
if (left.length !== right.length) {
return false;
}
for (let i = 0; i < left.length; i++) {
if (left[i] !== right[i]) {
return false;
}
}
return true;
};
// diffSimple (hierarchically) compares two objects and return true if they are different
//
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
//
// IMPORTANT:
// (5) 'right' may have ore fields than 'left'
//
// example:
//
// diffSimple({a:'a'}, {a:'a', b:'b'}) === false
//
const diffSimple = (left, right) => {
const keys = Object.keys(left);
for (const key of keys) {
const value = right[key];
if (Array.isArray(value)) {
if (!shallowCompareArrays(left[key], value)) {
return true;
}
}
else if (typeof left[key] === 'object' && left[key] !== null) {
if (diffSimple(left[key], value)) {
return true;
}
}
else {
if (left[key] !== value) {
return true;
}
}
}
return false; // all equal
};
// email2key converts email address to key by removing the @ mark and dots
const email2key = (email) => {
return email.toLowerCase().replace(/[@\.]/g, '_');
};
// empty2blank will replace empty with '' recursively on SIMPLE objects
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
// (5) null or undefined will be converted to ''
const empty2blank = (obj, empty = '__EMPTY__', keepUndefined = false) => Object.keys(obj).reduce((acc, curr) => ({
...acc,
[curr]: obj[curr] === null || obj[curr] === undefined
? keepUndefined
? obj[curr]
: ''
: Array.isArray(obj[curr])
? obj[curr].map((x) => (x === empty ? '' : x))
: typeof obj[curr] === 'object'
? empty2blank(obj[curr], empty)
: obj[curr] === empty
? ''
: obj[curr],
}), {});
// getObjectKeys (hierarchically) returns all keys (and subkeys) of an object
// NOTE: will not recurse into array
const getObjectKeys = (obj, useBracesToIndicateNesting = true) => {
const results = [];
for (const key of Object.keys(obj)) {
const value = obj[key];
results.push(key);
if (typeof value === 'object' && !Array.isArray(value)) {
if (useBracesToIndicateNesting) {
results.push('{');
}
getObjectKeys(value, useBracesToIndicateNesting).forEach(v => results.push(v));
if (useBracesToIndicateNesting) {
results.push('}');
}
}
}
return results;
};
const hasProp = (object, propertyName) => {
return Object.prototype.hasOwnProperty.call(object, propertyName);
};
// this function will remove excess decimal digits by truncating the value
// NOTE: this function will round up or down
const limitNumDecimals = (val, maxDigits = 2) => {
return Number(Number.parseFloat(String(val)).toFixed(maxDigits));
};
// Locales helps to extract localized messages an a resources object such as:
// const resources = {
// en: {
// hello: 'Hello World',
// home: {
// title: 'Main page',
// },
// err: {
// internal: 'INTERNAL_ERROR: Some problem happened, please contact us',
// },
// },
// pt: {
// hello: 'Alô Mundo',
// home: {
// title: 'Página principal',
// },
// err: {
// internal: 'ERRO_INTERNO: Aconteceu algum problema, por favor nos contactar',
// },
// },
// };
class Locales {
// NOTE: resources is stored "byRef"
constructor(resources, locale = 'en', country = 'us') {
this.getLocale = () => this.locale;
this.setLocale = (locale) => (this.locale = locale);
this.getCountry = () => this.country;
this.setCountry = (country) => (this.country = country);
this.getIndexDay = () => (this.country === 'us' ? 1 : 0);
this.getIndexMonth = () => (this.country === 'us' ? 0 : 1);
this.getFirstFieldMax = () => (this.country === 'us' ? 12 : 31);
this.getSecondFieldMax = () => (this.country === 'us' ? 31 : 12);
this.getDateFormat = () => (this.country === 'us' ? 'MM/DD/YYYY' : 'DD/MM/YYYY');
this.translate = (path, defaultMessage = '') => {
// check for locale in resources
if (!hasProp(this.resources, this.locale)) {
return `INTERNAL_ERROR: cannot find locale ${this.locale} in resources object`;
}
// resources
const res = this.resources[this.locale];
// check for path
if (!path) {
return 'INTERNAL_ERROR: path variable must not be empty';
}
// extract localized message
const list = path.split('.');
const msg = list.reduce((acc, curr) => {
if (hasProp(acc, curr)) {
return acc[curr];
}
return '';
}, res);
// default message?
if (!msg) {
return defaultMessage || `INTERNAL_ERROR: cannot find message with path = ${path}`;
}
// results
return msg;
};
this.resources = resources;
this.locale = locale;
this.country = country;
}
}
let MLOG_VERBOSE = true;
let ELOG_VERBOSE = true;
let ELOG_PREFIX = '[ERROR]';
// setMlog sets message logging verbose mode
const setMlog = (verbose) => (MLOG_VERBOSE = verbose);
// setElog sets error message logging verbose mode
const setElog = (verbose) => (ELOG_VERBOSE = verbose);
// setElogPrefix sets error log prefix
const setElogPrefix = (prefix) => (ELOG_PREFIX = prefix);
// mlog logs message, if verbose mode is on
const mlog = (message) => {
if (MLOG_VERBOSE) {
if (typeof message === 'string' ||
typeof message === 'number' ||
typeof message === 'boolean') {
console.log(message);
}
else {
console.log(JSON.stringify(message, undefined, 2));
}
}
};
// elog logs error, if vermobse mode is on, and returns the formatted error message
const elog = (error) => {
let msg = '';
if (error.message && typeof error.message === 'string') {
error.message.replace(`${ELOG_PREFIX} `, '');
msg = `${ELOG_PREFIX} ${error.message}`;
}
else {
if (typeof error === 'string' || typeof error === 'number' || typeof error === 'boolean') {
msg = `${ELOG_PREFIX} ${error}`;
}
else {
msg = `${ELOG_PREFIX}\n${JSON.stringify(error, undefined, 2)}`;
}
}
msg = msg.replace(`${ELOG_PREFIX} ${ELOG_PREFIX}`, ELOG_PREFIX);
if (ELOG_VERBOSE) {
console.log(msg);
}
return msg;
};
// makeGetField makes a getField function
const makeGetField = (obj, TT) => (fieldName) => {
// check if field exists
if (!Object.prototype.hasOwnProperty.call(obj, fieldName)) {
throw new Error(`cannot find ${fieldName}`);
}
// check if type is correct
const value = obj[fieldName];
if (typeof value !== TT) {
throw new Error(`type of ${fieldName} is incorrect`);
}
// results
return value;
};
// makeSetFiled makes a setField function
const makeSetField = (obj, onChange, TT) => (fieldName, value) => {
// check if field exists
if (!Object.prototype.hasOwnProperty.call(obj, fieldName)) {
throw new Error(`cannot find ${fieldName}`);
}
// previous value
const oldValue = obj[fieldName];
// check if type is correct
if (typeof oldValue !== TT) {
throw new Error(`type of ${fieldName} is incorrect`);
}
// check if value has been changed
if (oldValue !== value) {
obj[fieldName] = value;
onChange();
}
};
// maybeCopySimple (hierarchically) copies some data from origin
// into destination, iff the origin data exists (not undefined / not null)
// but it does copy empty strings and numbers
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
const maybeCopySimple = (destination, origin) => {
for (const key of Object.keys(destination)) {
if (hasProp(origin, key)) {
const value = origin[key];
if (value !== undefined && value !== null) {
if (Array.isArray(value)) {
destination[key] = value.slice(0);
}
else if (typeof value === 'object') {
maybeCopySimple(destination[key], value);
}
else {
destination[key] = value;
}
}
}
}
};
const numOnly = (value) => {
return value.replace(/[\D\s\._\-]+/g, '');
};
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const unixTimeNow = () => Math.floor(Date.now() / 1000);
exports.Locales = Locales;
exports.allFilled = allFilled;
exports.blank2empty = blank2empty;
exports.camelize = camelize;
exports.cloneSimple = cloneSimple;
exports.copySimple = copySimple;
exports.diffSimple = diffSimple;
exports.elog = elog;
exports.email2key = email2key;
exports.empty2blank = empty2blank;
exports.filled = filled;
exports.getObjectKeys = getObjectKeys;
exports.hasProp = hasProp;
exports.limitNumDecimals = limitNumDecimals;
exports.makeGetField = makeGetField;
exports.makeSetField = makeSetField;
exports.maybeCopySimple = maybeCopySimple;
exports.mlog = mlog;
exports.numOnly = numOnly;
exports.setElog = setElog;
exports.setElogPrefix = setElogPrefix;
exports.setMlog = setMlog;
exports.shallowCompareArrays = shallowCompareArrays;
exports.sleep = sleep;
exports.unixTimeNow = unixTimeNow;

@@ -1,1 +0,389 @@

const e=e=>""!==e&&"null"!==e,t=(t,r)=>{let o;o=r?Object.keys(t).filter(e=>!r.includes(e)):Object.keys(t);for(const r of o)if(!e(t[r]))return!1;return!0},r=(e,t="__EMPTY__",o=!1)=>Object.keys(e).reduce((s,n)=>({...s,[n]:null===e[n]||void 0===e[n]?o?e[n]:t:Array.isArray(e[n])?e[n].map(e=>""===e?t:e):"object"==typeof e[n]?r(e[n],t):""===e[n]?t:e[n]}),{}),o=(e,t=!1,r="_")=>t?e.split(r).map(e=>e.toLowerCase().replace(/./,e=>e.toUpperCase())).join(""):e.split(r).map((e,t)=>t>0?e.toLowerCase().replace(/./,e=>e.toUpperCase()):e.toLowerCase()).join(""),s=e=>Object.keys(e).reduce((t,r)=>({...t,[r]:Array.isArray(e[r])?e[r].slice(0):"object"==typeof e[r]?s(e[r]):e[r]}),{}),n=(e,t)=>{const r=Object.keys(e);for(const o of r){const r=t[o];Array.isArray(r)?e[o]=r.slice(0):"object"==typeof r?n(e[o],r):e[o]=r}},c=(e,t)=>{if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0},i=(e,t)=>{const r=Object.keys(e);for(const o of r){const r=t[o];if(Array.isArray(r)){if(!c(e[o],r))return!0}else if("object"==typeof e[o]&&null!==e[o]){if(i(e[o],r))return!0}else if(e[o]!==r)return!0}return!1},a=e=>e.toLowerCase().replace(/[@\.]/g,"_"),l=(e,t="__EMPTY__",r=!1)=>Object.keys(e).reduce((o,s)=>({...o,[s]:null===e[s]||void 0===e[s]?r?e[s]:"":Array.isArray(e[s])?e[s].map(e=>e===t?"":e):"object"==typeof e[s]?l(e[s],t):e[s]===t?"":e[s]}),{}),y=(e,t=!0)=>{const r=[];for(const o of Object.keys(e)){const s=e[o];r.push(o),"object"!=typeof s||Array.isArray(s)||(t&&r.push("{"),y(s,t).forEach(e=>r.push(e)),t&&r.push("}"))}return r},u=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),f=(e,t=2)=>Number(Number.parseFloat(String(e)).toFixed(t));class p{constructor(e,t="en",r="us"){this.getLocale=()=>this.locale,this.setLocale=e=>this.locale=e,this.getCountry=()=>this.country,this.setCountry=e=>this.country=e,this.getIndexDay=()=>"us"===this.country?1:0,this.getIndexMonth=()=>"us"===this.country?0:1,this.getFirstFieldMax=()=>"us"===this.country?12:31,this.getSecondFieldMax=()=>"us"===this.country?31:12,this.getDateFormat=()=>"us"===this.country?"MM/DD/YYYY":"DD/MM/YYYY",this.translate=(e,t="")=>{if(!u(this.resources,this.locale))return`INTERNAL_ERROR: cannot find locale ${this.locale} in resources object`;const r=this.resources[this.locale];if(!e)return"INTERNAL_ERROR: path variable must not be empty";const o=e.split(".").reduce((e,t)=>u(e,t)?e[t]:"",r);return o||(t||`INTERNAL_ERROR: cannot find message with path = ${e}`)},this.resources=e,this.locale=t,this.country=r}}let h=!0,b=!0,g="[ERROR]";const j=e=>h=e,O=e=>b=e,d=e=>g=e,m=e=>{h&&("string"==typeof e||"number"==typeof e||"boolean"==typeof e?console.log(e):console.log(JSON.stringify(e,void 0,2)))},w=e=>{let t="";return e.message&&"string"==typeof e.message?(e.message.replace(`${g} `,""),t=`${g} ${e.message}`):t="string"==typeof e||"number"==typeof e||"boolean"==typeof e?`${g} ${e}`:`${g}\n${JSON.stringify(e,void 0,2)}`,t=t.replace(`${g} ${g}`,g),b&&console.log(t),t},A=(e,t)=>r=>{if(!Object.prototype.hasOwnProperty.call(e,r))throw new Error(`cannot find ${r}`);const o=e[r];if(typeof o!==t)throw new Error(`type of ${r} is incorrect`);return o},R=(e,t,r)=>(o,s)=>{if(!Object.prototype.hasOwnProperty.call(e,o))throw new Error(`cannot find ${o}`);const n=e[o];if(typeof n!==r)throw new Error(`type of ${o} is incorrect`);n!==s&&(e[o]=s,t())},$=(e,t)=>{for(const r of Object.keys(e))if(u(t,r)){const o=t[r];null!=o&&(Array.isArray(o)?e[r]=o.slice(0):"object"==typeof o?$(e[r],o):e[r]=o)}},E=e=>e.replace(/[\D\s\._\-]+/g,""),_=e=>new Promise(t=>setTimeout(t,e)),M=()=>Math.floor(Date.now()/1e3);export{p as Locales,t as allFilled,r as blank2empty,o as camelize,s as cloneSimple,n as copySimple,i as diffSimple,w as elog,a as email2key,l as empty2blank,e as filled,y as getObjectKeys,u as hasProp,f as limitNumDecimals,A as makeGetField,R as makeSetField,$ as maybeCopySimple,m as mlog,E as numOnly,O as setElog,d as setElogPrefix,j as setMlog,c as shallowCompareArrays,_ as sleep,M as unixTimeNow};
const filled = (entry) => {
if (entry === '' || entry === 'null') {
return false;
}
return true;
};
// allFilled checks if all 'root-level' properties of object are filled (not '', not 'null')
const allFilled = (obj, ignoredKeys) => {
let keys;
if (ignoredKeys) {
keys = Object.keys(obj).filter(key => !ignoredKeys.includes(key));
}
else {
keys = Object.keys(obj);
}
for (const key of keys) {
if (!filled(obj[key])) {
return false;
}
}
return true;
};
// blank2empty will replace '' with empty recursively on SIMPLE objects
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
// (5) null or undefined will be converted to EMPTY
const blank2empty = (obj, empty = '__EMPTY__', keepUndefined = false) => Object.keys(obj).reduce((acc, curr) => ({
...acc,
[curr]: obj[curr] === null || obj[curr] === undefined
? keepUndefined
? obj[curr]
: empty
: Array.isArray(obj[curr])
? obj[curr].map((x) => (x === '' ? empty : x))
: typeof obj[curr] === 'object'
? blank2empty(obj[curr], empty)
: obj[curr] === ''
? empty
: obj[curr],
}), {});
const camelize = (name, firstUpper = false, separator = '_') => {
if (firstUpper) {
return name
.split(separator)
.map(w => w.toLowerCase().replace(/./, m => m.toUpperCase()))
.join('');
}
return name
.split(separator)
.map((w, i) => {
if (i > 0) {
return w.toLowerCase().replace(/./, m => m.toUpperCase());
}
return w.toLowerCase();
})
.join('');
};
// cloneSimple (hierarchically) creates a copy of "simple" entries of object
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
const cloneSimple = (obj) => Object.keys(obj).reduce((acc, curr) => ({
...acc,
[curr]: Array.isArray(obj[curr])
? obj[curr].slice(0)
: typeof obj[curr] === 'object'
? cloneSimple(obj[curr])
: obj[curr],
}), {});
// copySimple (hierarchically) copies all entries of object into destination
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
const copySimple = (destination, origin) => {
const keys = Object.keys(destination);
for (const key of keys) {
const value = origin[key];
if (Array.isArray(value)) {
destination[key] = value.slice(0);
}
else if (typeof value === 'object') {
copySimple(destination[key], value);
}
else {
destination[key] = value;
}
}
};
// shallowCompareArrays returns true if two arrays are equal to each other
// NOTE: the type of the array entries must be "fundamental"
const shallowCompareArrays = (left, right) => {
if (left.length !== right.length) {
return false;
}
for (let i = 0; i < left.length; i++) {
if (left[i] !== right[i]) {
return false;
}
}
return true;
};
// diffSimple (hierarchically) compares two objects and return true if they are different
//
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
//
// IMPORTANT:
// (5) 'right' may have ore fields than 'left'
//
// example:
//
// diffSimple({a:'a'}, {a:'a', b:'b'}) === false
//
const diffSimple = (left, right) => {
const keys = Object.keys(left);
for (const key of keys) {
const value = right[key];
if (Array.isArray(value)) {
if (!shallowCompareArrays(left[key], value)) {
return true;
}
}
else if (typeof left[key] === 'object' && left[key] !== null) {
if (diffSimple(left[key], value)) {
return true;
}
}
else {
if (left[key] !== value) {
return true;
}
}
}
return false; // all equal
};
// email2key converts email address to key by removing the @ mark and dots
const email2key = (email) => {
return email.toLowerCase().replace(/[@\.]/g, '_');
};
// empty2blank will replace empty with '' recursively on SIMPLE objects
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
// (5) null or undefined will be converted to ''
const empty2blank = (obj, empty = '__EMPTY__', keepUndefined = false) => Object.keys(obj).reduce((acc, curr) => ({
...acc,
[curr]: obj[curr] === null || obj[curr] === undefined
? keepUndefined
? obj[curr]
: ''
: Array.isArray(obj[curr])
? obj[curr].map((x) => (x === empty ? '' : x))
: typeof obj[curr] === 'object'
? empty2blank(obj[curr], empty)
: obj[curr] === empty
? ''
: obj[curr],
}), {});
// getObjectKeys (hierarchically) returns all keys (and subkeys) of an object
// NOTE: will not recurse into array
const getObjectKeys = (obj, useBracesToIndicateNesting = true) => {
const results = [];
for (const key of Object.keys(obj)) {
const value = obj[key];
results.push(key);
if (typeof value === 'object' && !Array.isArray(value)) {
if (useBracesToIndicateNesting) {
results.push('{');
}
getObjectKeys(value, useBracesToIndicateNesting).forEach(v => results.push(v));
if (useBracesToIndicateNesting) {
results.push('}');
}
}
}
return results;
};
const hasProp = (object, propertyName) => {
return Object.prototype.hasOwnProperty.call(object, propertyName);
};
// this function will remove excess decimal digits by truncating the value
// NOTE: this function will round up or down
const limitNumDecimals = (val, maxDigits = 2) => {
return Number(Number.parseFloat(String(val)).toFixed(maxDigits));
};
// Locales helps to extract localized messages an a resources object such as:
// const resources = {
// en: {
// hello: 'Hello World',
// home: {
// title: 'Main page',
// },
// err: {
// internal: 'INTERNAL_ERROR: Some problem happened, please contact us',
// },
// },
// pt: {
// hello: 'Alô Mundo',
// home: {
// title: 'Página principal',
// },
// err: {
// internal: 'ERRO_INTERNO: Aconteceu algum problema, por favor nos contactar',
// },
// },
// };
class Locales {
// NOTE: resources is stored "byRef"
constructor(resources, locale = 'en', country = 'us') {
this.getLocale = () => this.locale;
this.setLocale = (locale) => (this.locale = locale);
this.getCountry = () => this.country;
this.setCountry = (country) => (this.country = country);
this.getIndexDay = () => (this.country === 'us' ? 1 : 0);
this.getIndexMonth = () => (this.country === 'us' ? 0 : 1);
this.getFirstFieldMax = () => (this.country === 'us' ? 12 : 31);
this.getSecondFieldMax = () => (this.country === 'us' ? 31 : 12);
this.getDateFormat = () => (this.country === 'us' ? 'MM/DD/YYYY' : 'DD/MM/YYYY');
this.translate = (path, defaultMessage = '') => {
// check for locale in resources
if (!hasProp(this.resources, this.locale)) {
return `INTERNAL_ERROR: cannot find locale ${this.locale} in resources object`;
}
// resources
const res = this.resources[this.locale];
// check for path
if (!path) {
return 'INTERNAL_ERROR: path variable must not be empty';
}
// extract localized message
const list = path.split('.');
const msg = list.reduce((acc, curr) => {
if (hasProp(acc, curr)) {
return acc[curr];
}
return '';
}, res);
// default message?
if (!msg) {
return defaultMessage || `INTERNAL_ERROR: cannot find message with path = ${path}`;
}
// results
return msg;
};
this.resources = resources;
this.locale = locale;
this.country = country;
}
}
let MLOG_VERBOSE = true;
let ELOG_VERBOSE = true;
let ELOG_PREFIX = '[ERROR]';
// setMlog sets message logging verbose mode
const setMlog = (verbose) => (MLOG_VERBOSE = verbose);
// setElog sets error message logging verbose mode
const setElog = (verbose) => (ELOG_VERBOSE = verbose);
// setElogPrefix sets error log prefix
const setElogPrefix = (prefix) => (ELOG_PREFIX = prefix);
// mlog logs message, if verbose mode is on
const mlog = (message) => {
if (MLOG_VERBOSE) {
if (typeof message === 'string' ||
typeof message === 'number' ||
typeof message === 'boolean') {
console.log(message);
}
else {
console.log(JSON.stringify(message, undefined, 2));
}
}
};
// elog logs error, if vermobse mode is on, and returns the formatted error message
const elog = (error) => {
let msg = '';
if (error.message && typeof error.message === 'string') {
error.message.replace(`${ELOG_PREFIX} `, '');
msg = `${ELOG_PREFIX} ${error.message}`;
}
else {
if (typeof error === 'string' || typeof error === 'number' || typeof error === 'boolean') {
msg = `${ELOG_PREFIX} ${error}`;
}
else {
msg = `${ELOG_PREFIX}\n${JSON.stringify(error, undefined, 2)}`;
}
}
msg = msg.replace(`${ELOG_PREFIX} ${ELOG_PREFIX}`, ELOG_PREFIX);
if (ELOG_VERBOSE) {
console.log(msg);
}
return msg;
};
// makeGetField makes a getField function
const makeGetField = (obj, TT) => (fieldName) => {
// check if field exists
if (!Object.prototype.hasOwnProperty.call(obj, fieldName)) {
throw new Error(`cannot find ${fieldName}`);
}
// check if type is correct
const value = obj[fieldName];
if (typeof value !== TT) {
throw new Error(`type of ${fieldName} is incorrect`);
}
// results
return value;
};
// makeSetFiled makes a setField function
const makeSetField = (obj, onChange, TT) => (fieldName, value) => {
// check if field exists
if (!Object.prototype.hasOwnProperty.call(obj, fieldName)) {
throw new Error(`cannot find ${fieldName}`);
}
// previous value
const oldValue = obj[fieldName];
// check if type is correct
if (typeof oldValue !== TT) {
throw new Error(`type of ${fieldName} is incorrect`);
}
// check if value has been changed
if (oldValue !== value) {
obj[fieldName] = value;
onChange();
}
};
// maybeCopySimple (hierarchically) copies some data from origin
// into destination, iff the origin data exists (not undefined / not null)
// but it does copy empty strings and numbers
// NOTE: (1) will NOT recurse into array
// (2) arrays must NOT have mixed types or objects;
// (3) arrays must only contain "simple" types
// (4) simple means: string, number, boolean
// i.e arrays must be "simple" as string[], number[], boolean[]
const maybeCopySimple = (destination, origin) => {
for (const key of Object.keys(destination)) {
if (hasProp(origin, key)) {
const value = origin[key];
if (value !== undefined && value !== null) {
if (Array.isArray(value)) {
destination[key] = value.slice(0);
}
else if (typeof value === 'object') {
maybeCopySimple(destination[key], value);
}
else {
destination[key] = value;
}
}
}
}
};
const numOnly = (value) => {
return value.replace(/[\D\s\._\-]+/g, '');
};
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
const unixTimeNow = () => Math.floor(Date.now() / 1000);
export { Locales, allFilled, blank2empty, camelize, cloneSimple, copySimple, diffSimple, elog, email2key, empty2blank, filled, getObjectKeys, hasProp, limitNumDecimals, makeGetField, makeSetField, maybeCopySimple, mlog, numOnly, setElog, setElogPrefix, setMlog, shallowCompareArrays, sleep, unixTimeNow };

9

package.json
{
"name": "@cpmech/basic",
"version": "4.6.0",
"version": "4.7.0",
"license": "MIT",

@@ -16,3 +16,3 @@ "author": {

"cov": "jest --coverage",
"build": "rm -rf dist && rollup --config ../rollup.config.js"
"build": "rm -rf dist && rollup --config rollup.config.js"
},

@@ -35,5 +35,2 @@ "files": [

"rollup": "^1.31.1",
"rollup-plugin-auto-external": "^2.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-terser": "^5.2.0",
"rollup-plugin-typescript2": "^0.26.0",

@@ -46,3 +43,3 @@ "ts-jest": "^25.2.1",

},
"gitHead": "f26d8e9d996a5bd8e2f0721864418bba344e120b"
"gitHead": "cb53cdd8d83c7ece9d9ff4ae5e7f1d151bee2036"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc