npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@huxy/utils

v2.1.14

Published

javascript function library

Downloads

55

Readme

utils

GitHub license npm version npm

a2o

const arr = [
  {
    key: 1,
    value: 't1',
  },
  {
    key: 2,
    value: 't2',
  },
  {
    key: 3,
    value: 't3',
  },
];

a2o(arr, 'key', 'value');

// {1: 't1', 2: 't2', 3: 't3'}

addAtNext/addAtPos/addNodes/editNodes/deleteNodes/moveNodes

addAtNext(tree, id, nodes, (idKey = 'id'), (childKey = 'children'));
addAtPos(tree, id, nodes, pos, (idKey = 'id'), (childKey = 'children'));
addNodes(tree, id, nodes, (idKey = 'id'), (childKey = 'children'));
editNodes(tree, id, nodes, (idKey = 'id'), (childKey = 'children'));
deleteNodes(tree, id, (idKey = 'id'), (childKey = 'children'));
moveNodes(tree, fromId, toId, pos, (idKey = 'id'), (childKey = 'children'));

addScript/addStyle

动态添加 scriptstyle

const loadScript = async url => {
  await addScript(url);
};
const loadStyleByUrl = async url => {
  await addStyle(url);
};
const addStyleByCode = addStyle(cssCode, 'css-hash');

arr2Tree

const arr = [
  {
    parentId: 1,
    id: 2,
    value: '1-1',
  },
  {
    parentId: 4,
    id: 5,
    value: '2-1',
  },
  {
    id: 4,
    value: '2',
  },
  {
    id: 1,
    value: '1',
  },
  {
    parentId: 1,
    id: 3,
    value: '1-2',
  },
  {
    parentId: 5,
    id: 6,
    value: '2-1-1',
  },
];

arr2Tree()(arr);

output: [
  {
    id: 4,
    value: '2',
    parentId: -1,
    children: [
      {
        parentId: 4,
        id: 5,
        value: '2-1',
        children: [
          {
            parentId: 5,
            id: 6,
            value: '2-1-1',
            children: [],
          },
        ],
      },
    ],
  },
  {
    id: 1,
    value: '1',
    parentId: -1,
    children: [
      {
        parentId: 1,
        id: 2,
        value: '1-1',
        children: [],
      },
      {
        parentId: 1,
        id: 3,
        value: '1-2',
        children: [],
      },
    ],
  },
];

arr2TreeByPath

const arr = [
  {
    path: '/home/p1',
    value: 'p1',
  },
  {
    path: '/404',
    value: '404',
  },
  {
    path: '/home/p1/sp2',
    value: 'sp12',
  },
  {
    path: '/home',
    value: 'home',
  },
  {
    path: '/home/p2/sp3',
    value: 'sp23',
  },
  {
    path: '/home/p2/sp2/sp1',
    value: 'sp221',
  },
  {
    path: '',
    value: 'root',
  },
  {
    path: '/home/p1/sp1',
    value: 'sp11',
  },
  {
    path: '/home/p2/sp2',
    value: 'sp22',
  },
  {
    path: '/home/p2/sp2/sp1',
    value: 'sp221',
  },
  {
    path: '/home/p2',
    value: 'p2',
  },
  {
    path: '/home/p3',
    value: 'p3',
  },
];

arr2TreeByPath(arr);

output: [
  {
    path: '',
    value: 'root',
    parentId: null,
    children: [
      {
        path: '/404',
        value: '404',
        parentId: '',
        children: [],
      },
      {
        path: '/home',
        value: 'home',
        parentId: '',
        children: [
          {
            path: '/home/p1',
            value: 'p1',
            parentId: '/home',
            children: [
              {
                path: '/home/p1/sp2',
                value: 'sp12',
                parentId: '/home/p1',
                children: [],
              },
              {
                path: '/home/p1/sp1',
                value: 'sp11',
                parentId: '/home/p1',
                children: [],
              },
            ],
          },
          {
            path: '/home/p2',
            value: 'p2',
            parentId: '/home',
            children: [
              {
                path: '/home/p2/sp3',
                value: 'sp23',
                parentId: '/home/p2',
                children: [],
              },
              {
                path: '/home/p2/sp2',
                value: 'sp22',
                parentId: '/home/p2',
                children: [
                  {
                    path: '/home/p2/sp2/sp1',
                    value: 'sp221',
                    parentId: '/home/p2/sp2',
                    children: [],
                  },
                  {
                    path: '/home/p2/sp2/sp1',
                    value: 'sp221',
                    parentId: '/home/p2/sp2',
                    children: [],
                  },
                ],
              },
            ],
          },
          {
            path: '/home/p3',
            value: 'p3',
            parentId: '/home',
            children: [],
          },
        ],
      },
    ],
  },
];

backTop

返回页面顶部按钮。

backTop(scrollHeight);
  • scrollHeight:出现 ‘返回顶部’ 按钮时的滚动距离,默认 0 。

rgba2hex

rgba2hex(111, 111, 111, 0.8);

// '#6f6f6fcc'

rmUnit

rmUnit('100px'); // Number: 100
rmUnit('60s', 's'); // Number: 60
  • unit:默认 px

hex2rgba

hex2rgba('ddd');

> // 'rgb(221,221,221)'

base2Ten

base2Ten(100, 16); // 256
base2Ten(100, 8); // 64
base2Ten(100); // 4

ten2Base

ten2Base(100, 16); // 64
ten2Base(100, 8); // 144
ten2Base(100); // 1100100

baseConversion

baseConversion(100, 8, 16); // 40

fetcher

import {fetcher} from '@huxy/utils';

const handler = response => {
  return response
    .json()
    .then(result => {
      result.code = result.code ?? response.status;
      result.msg = result.message ?? result.msg ?? response.statusText;
      const {msg, code} = result;
      if (code === 401) {
        message.error(msg);
        logout(true);
        throw {code, message: msg};
      }
      if (!success_code.includes(code)) {
        throw {code, message: msg};
      }
      return result;
    })
    .catch(error => {
      message.error(error.message);
      throw error.message;
    });
};

const fetchApi = fetcher(handler);

const fetch = ({method, url, ...opt}) => fetchApi(method)(`${TARGET}${url}`, {...opt, headers: getToken(), credentials: 'omit'});

cacheData

const {record, undo, redo, clean} = cacheData();

cancelablePromise

const {promiseFn, cancelFn} = cancelablePromise(components, {delay: suspenseConfig.delay, msg: {timeout: suspenseConfig.timeoutMsg}});

promiseFn.then().catch();

changePos

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];

changePos(arr, 2, 7);

// [1, 2, 8, 4, 5, 6, 7, 3, 9]

classifyArr

const arr=[
  {
    name:'test1',
    value:'t1',
  },
  {
    name:'test2',
    value:'t2',
  },
  {
    name:'test1',
    value:'t3',
  },
  {
    name:'test2',
    value:'t4',
  },
];

classifyArr(arr)

output:

{
  "test1": [
    {
      "name": "test1",
      "value": "t1"
    },
    {
      "name": "test1",
      "value": "t3"
    }
  ],
  "test2": [
    {
      "name": "test2",
      "value": "t2"
    },
    {
      "name": "test2",
      "value": "t4"
    }
  ]
}

clone

clone(arr | object);

compareVersion

compareVersion(a, b, key = '.');

compareVersion('1.5.111', '1.7.0'); // 2
compareVersion('1.105.1', '2.0.0'); // 3
compareVersion('10.0.1', '10.0.22'); // 1
compareVersion('3.2.1', '3.2.1'); // 0
compareVersion('2_22_1', '2_9_11', '_'); // 0

返回值:

- 0:a >= b
- 1:a < b,阶段版本号需更新
- 2:a < b,子版本号需更新
- 3:a < b,主版本号需更新

compose

const a = x => x + 10;

const b = x => x * 10;

compose(b, a)(2); // 120

copyToClipboard

> copyToClipboard(text)

createTextElement/createElement/createNode

createTextElement(text);

createElement(type, props, ...children);

createNode({type: '', props: {}});

curry

const arr = [
  {
    name: 'test1',
    value: 't1',
  },
  {
    name: 'test2',
    value: 't2',
  },
  {
    name: 'test1',
    value: 't3',
  },
  {
    name: 'test2',
    value: 't4',
  },
];

const fn = (name, value) => arr.filter(item => item.name === name).filter(item => item.value === value);

const a = curry(fn)('test1');

a('t3');

output: [
  {
    name: 'test1',
    value: 't3',
  },
];

cyclic

cyclic(object); // true | false

addDays/addMonths/addYears/addHours

addDays(2, '2022-01-01'); // Mon Jan 03 2022 08:00:00 GMT+0800 (中国标准时间)

addMonths(3); // Sat Jun 25 2022 17:44:47 GMT+0800 (中国标准时间)

getLeaveTime

getLeaveTime('2022-10-1'); // '189天6小时12分11秒'

weekDate/monthDate

weekDate();

output: ['2022-03-21T09:48:44.098Z', '2022-03-27T09:48:44.098Z'];

dash2camel

dash2camel('add-file-name'); // addFileName
dash2camel('add_file_name', '_'); // addFileName

dataURLtoFile

dataURLtoFile('data:image/png;base64,xxx...', test.png);

debounce

debounce(func, (delay = 60));

dropInfo

元素触发事件弹出层

dropInfo(triggerEle, showEle, type = 'horizontal');

- triggerEle:触发元素
- showEle:弹出层内容
- type:弹层位置样式,horizontal | vertical

dlfile

dlfile(url, name);

emitter

const {on, emit, off} = emitter();

equal

equal(a, b); // true | false

filter

const arr = [
  {
    name: 'test1',
    value: 't1',
  },
  {
    name: 'test2',
    value: 't2',
  },
  {
    name: 'test1',
    value: 't3',
  },
  {
    name: 'test2',
    value: 't4',
  },
];

filter(arr, 'est1', 'name');

output: [
  {
    name: 'test1',
    value: 't1',
  },
  {
    name: 'test1',
    value: 't3',
  },
];

filterList

filterList(data, keyword, str2Dom /*高亮元素*/, (fields = 'name'), (idKey = 'id'), (childKey = 'children'), (exact = false));

findChildEle

findChildEle(target, classname);

返回当前元素下类名为 classname 的所有元素,没找到则返回 null

findMax

findMax('ghfdj53785bhb4289yb3b478'); // 53785

firstUpper

firstUpper('hello world'); // 'Hello world'

fixPath

fixPath('//a/b//c'); // '/a/b/c'

fixRoute

fixRoute('/a/b/e/'); // /a/b/e

fixSize

fixSize(img, ratio = 1);

根据父元素宽高比设置元素宽度比例。

fixFileSizeUnit

fixFileSizeUnit(10000); // 9.766 KB
fixFileSizeUnit(2000000); // 1.907 M

fixTimeUnit

fixTimeUnit(1000); // 16m40s
fixTimeUnit(20000); // 5h33m20s

flatten

const arr = [
  {
    name: 'test1',
    value: 't1',
    children: [
      {
        name: 'test11',
        value: 't11',
      },
      {
        name: 'test12',
        value: 't12',
      },
    ],
  },
  {
    name: 'test2',
    value: 't2',
  },
  {
    name: 'test1',
    value: 't3',
    children: [
      {
        name: 'test31',
        value: 't31',
      },
      {
        name: 'test32',
        value: 't32',
        children: [
          {
            name: 'test321',
            value: 't321',
          },
        ],
      },
    ],
  },
  {
    name: 'test2',
    value: 't4',
  },
];

flatten(arr);

output: [
  {
    name: 'test1',
    value: 't1',
  },
  {
    name: 'test2',
    value: 't2',
  },
  {
    name: 'test1',
    value: 't3',
  },
  {
    name: 'test2',
    value: 't4',
  },
  {
    name: 'test11',
    value: 't11',
  },
  {
    name: 'test12',
    value: 't12',
  },
  {
    name: 'test31',
    value: 't31',
  },
  {
    name: 'test32',
    value: 't32',
  },
  {
    name: 'test321',
    value: 't321',
  },
];

formatNum

formatNum(12345678); // '12,345,678'

getTime/formatTime

getTime(); // [2022, 3, 25, 18, 4, 36, 5]

formatTime(); // '2022-03-25 18:04:36'

fullScreen/watchScreen

fullScreen(element);

watchScreen(callback); // 全屏变化时执行回调

getElementsSize

const {width, height, top, left, ...rest} = getElementsSize(ele);

getOffset

const {top, left} = getOffset(ele);

getParams

getParams('/a/b?name=hhh&age=18')

output:

{
  "path": "/a/b",
  "params": {
    "name": "hhh",
    "age": "18"
  }
}

getPosition

const {width, height, top, left, ...rest} = getPosition(ele);

getSelected

const arr = [
  {
    name: 'test1',
    value: 't1',
    children: [
      {
        name: 'test11',
        value: 't11',
      },
      {
        name: 'test12',
        value: 't12',
      },
    ],
  },
  {
    name: 'test2',
    value: 't2',
  },
  {
    name: 'test1',
    value: 't3',
    children: [
      {
        name: 'test31',
        value: 't31',
      },
      {
        name: 'test32',
        value: 't32',
        children: [
          {
            name: 'test321',
            value: 't321',
          },
        ],
      },
    ],
  },
  {
    name: 'test2',
    value: 't4',
  },
];

getSelected(arr, 't32', 'value');

output: [
  {
    name: 'test1',
    value: 't3',
  },
  {
    name: 'test32',
    value: 't32',
  },
];

getTextSize

const {width, height, top, left, ...rest} = getTextSize(text);

getTouchPosition/getRelative

const {touchX, touchY} = getTouchPosition(event);

const {x, y} = getRelative(event, ref);

getType

getType(); // 'undefined'
getType(''); // 'string'
getType(222); // 'number'
getType([]); // 'array'

getValue

const obj = {
  a: {
    b: {
      c: 4444,
    },
    b1: {},
  },
};

getValue(obj, 'a.b.c'); // 4444

getValue(obj, 'a.b.d'); // undefined

getViewportSize

const {width, height} = getViewportSize(element);

hasClass/addClass/removeClass/toggleClass

hasClass(ele, 'class1');
addClass(ele, 'class1');
removeClass(ele, 'class1');
toggleClass(ele, 'class1');

hasProp

const a = {b: undefined};

hasProp(a, 'b'); // true

isArray/isValidArr/isValidObj/isAsync/isObject/isFunction/isError/isRegExp/isElement/isUrl/isDate/isBase64Image

isArray([]); // true
isValidArr([1]); // true
isObject({}); // true
isValidObj({}); // false
isFunction(() => {}); // true
isError(new Error()); // true
isRegExp(/\d+/); // true
isElement(<span>1</span>); // true
isAsync(new Promise((res, rej) => {})); // true
isUrl('http://abc.com'); // true
isDate('2022', '10', '11'); // true
isBase64Image('data:image/png;base64,test'); // [data:image/png;base64,test, png]

isBrowser/isIE/isTouch

isBrowser();
isIE();
isTouch();

isReactEle/isRef

isReactEle(value);
isRef(value);

isWechat

判断是否为微信浏览器

isWechat(); // false

loadImage/loadBase64/loadBase64ByUrl/imgtocanvas

const img = await loadImage(url);
const base64 = await loadBase64(img);

const base64 = await loadBase64ByUrl(url);

const canvas = imgtocanvas(img);

memoize

const fn = n => console.log(n);
const m = memoize(fn);
m(3);
m(3);

// 3 只打印一次

merge/mergeObj/mergeArr

const a={
  name:'t1',
  children: [
    {
      name: 't11',
    },
    {
      name: 't12',
    },
  ],
};

const b={
  name:'t2',
  children: [
    {
      name: 't21',
    },
    {
      name: 't22',
    },
  ],
};

const c={
  age: 18,
  children: [
    {
      age: 20,
    },
    {
      age: 22,
    },
  ],
};

merge(a,b,c);

output:

{
  "name": "t2",
  "children": [
    {
      "name": "t21",
      "age": 20
    },
    {
      "name": "t22",
      "age": 22
    }
  ],
  "age": 18
}

message

message.success(content, delay, onClose);

- content:文本信息
- delay:持续时间
- onClose:关闭回调

message.success('success');
message.warn('warn');
message.error('error');
message.info('info');

obj2arr/arr2obj

const a={
  name:'t1',
  age: 18,
  id:'123',
};

obj2arr(a)

output:

[
  {
    "name": "name",
    "value": "t1"
  },
  {
    "name": "age",
    "value": 18
  },
  {
    "name": "id",
    "value": "123"
  }
]

const b=[
  {
    name:'t1',
    value:'t11',
  },
  {
    name:'t2',
    value:'t22',
  },
  {
    name:'t3',
    value:'t33',
  },
];

arr2obj(b)

output:

{
  "t1": "t11",
  "t2": "t22",
  "t3": "t33"
}

obj2str/arr2str/json2str

const c = {
  age: 18,
  children: [
    {
      age: 20,
    },
    {
      age: 22,
    },
  ],
};

json2str(c);

output: '{age=18, children={0={age=20}, 1={age=22}}}';

once

const t = () => console.log('test');

const runOne = once(t);

runOne(); // test
runOne(); // 不执行

padStart

padStart('123', 6); // 000123

padStart('abc', 5, '#'); // ##abc

params2data

const a = {
  name: 't1',
  age: 18,
  id: '123',
};

params2data(a); // FormData {}

params2str

const a = {
  name: 't1',
  age: 18,
  id: '123',
};

params2str(a); // '?name=t1&age=18&id=123'

paseXml

const {xml2Obj, obj2Xml} = paseXml;

xml2Obj(`<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1348831860</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[this is a test]]></Content>
  <MsgId>1234567890123456</MsgId>
  <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
</xml>`)

result:
{
  "obj": {
    "CreateTime": "1348831860",
    "MsgId": "1234567890123456",
    "MsgDataId": "xxxx",
    "Idx": "xxxx",
    "ToUserName": "toUser",
    "FromUserName": "fromUser",
    "MsgType": "text",
    "Content": "this is a test"
  },
  "types": {
    "CreateTime": "base",
    "MsgId": "base",
    "MsgDataId": "base",
    "Idx": "base",
    "ToUserName": "data",
    "FromUserName": "data",
    "MsgType": "data",
    "Content": "data"
  }
}

obj2Xml({
  "CreateTime": "1348831860",
  "MsgId": "1234567890123456",
  "MsgDataId": "xxxx",
  "Idx": "xxxx",
  "ToUserName": "toUser",
  "FromUserName": "fromUser",
  "MsgType": "text",
  "Content": "this is a test"
}, {
  "CreateTime": "base",
  "MsgId": "base",
  "MsgDataId": "base",
  "Idx": "base",
  "ToUserName": "data",
  "FromUserName": "data",
  "MsgType": "data",
  "Content": "data"
})

result:
<xml>\n    <CreateTime>1348831860</CreateTime>\n<MsgId>1234567890123456</MsgId>\n<MsgDataId>xxxx</MsgDataId>\n<Idx>xxxx</Idx>\n<ToUserName><![CDATA[toUser]]></ToUserName>\n<FromUserName><![CDATA[fromUser]]></FromUserName>\n<MsgType><![CDATA[text]]></MsgType>\n<Content><![CDATA[this is a test]]></Content>\n\n  </xml>

pick

const a = {
  name: 't1',
  age: 18,
  id: '123',
};

pick(a, ['id', 'name']); // {id: '123', name: 't1'}

promisify

promisify(func)(...args);

randNum/randStr/randColor/randTrue/randItem/randPercent

randNum(5); // 5
randStr(8); // 'czqx7vhu'
randColor(); // '#39a645'
randTrue(); // false
randItem([1, 3, 5, 7, 9]); // 3
randPercent(4); // [54, 13, 30, 3]
randPercent(5, 80); // [5, 40, 12, 11, 12]

resize

const {bind, unbind, destroy} = resize(element);

bind(callback);
unbind(callback);
destroy();

scrollToTop/scrollToAnchor/scrollTop

scrollToTop((top = 0)); // 滚动到指定位置
scrollToAnchor(ref); // 滚动到元素位置
scrollTop(); // 滚动到顶部

viewHeight/docHeight/isScrollBottom

viewHeight(); // 视图高度
docHeight(); // 文档高度
isScrollBottom(); // 是否滚到底部

selectedHandle

selectedHandle((data, i, parentId) => {
  console.log(data, i, parentId);
  return data[i]; // 选中id的item
})(arr, id);

session

const {get, set, rm, clear} = session;

get(name);
set(name, data);
rm(name);
clear();

setStyle

setStyle(ele, (styles = {}), (reset = false));

sleep

await sleep((ms = 350), (unit = 'ms'));

await sleep(2, 'm');
  • delay: 等待时间数值
  • unit: 单位。毫秒、秒、分、时、天。ms | s | m | h | d 。默认 ms

sort

const a = [
  {
    name: 't1',
    age: 33,
  },
  {
    name: 't2',
    age: 12,
  },
  {
    name: 't3',
    age: 22,
  },
];

sort(a, 'age');

output: [
  {
    name: 't2',
    age: 12,
  },
  {
    name: 't3',
    age: 22,
  },
  {
    name: 't1',
    age: 33,
  },
];

storage

const {get, set, rm, clear} = storage;

get(name);
set(name, data);
rm(name);
clear();

createStore

const {getState, setState, subscribe, clean} = createStore();

str2code

str2code('console.log(123)'); // 123

str2Html

str2Html('<a>link</a>'); // NodeList [a]

getExplore

getExplore(); // {type: 'Chrome', version: '99.0.4844.51'}

getOsInfo

getOsInfo(); // {type: 'macOS', version: '10.15.7'}

sysLang

sysLang(); // 'zh'

deviceType

deviceType(); // 'Desktop'

throttle

const throttleFn = throttle(fn, (delay = 60));

getMonthDays

getMonthDays(); // 31

timestamp

timestamp(); // 48620100.70000002

touchEvent

const destroy = touchEvent(startEvent, moveEvent, endEvent, ref);
  • startEvent:touchstart 或 mousedown 执行的事件
  • moveEvent:touchmove 或 mousemove 执行的事件
  • endEvent:touchend 或 mouseup 执行的事件
  • ref:容器元素,默认 document

返回 destroy 函数,执行 destroy() 即可销毁事件。

traverItem

traverItem((item, parent, index, hasChild) => {
  console.log(item, parent, index, hasChild);
})(arr, childKey);

- fn:回调函数
	- item:当前节点数据
	- parent:父节点数据
	- index:当前节点下标
	- hasChild:是否有子节点

- arr:树对象
- childKey:子节点 `key` 值,默认 `children`

traverList

traverItem(data => {
  console.log(data);
})(arr, childKey);

unique

const a = [
  {
    name: 't1',
    age: 33,
  },
  {
    name: 't2',
    age: 12,
  },
  {
    name: 't1',
    age: 22,
  },
];

unique(a, 'name');

output: [
  {
    name: 't1',
    age: 33,
  },
  {
    name: 't2',
    age: 12,
  },
];

updateId

const a = [
  {
    name: 't1',
    age: 33,
  },
  {
    name: 't2',
    age: 12,
  },
  {
    name: 't3',
    age: 22,
  },
];

updateId(a, 'id');

output: [
  {
    name: 't1',
    age: 33,
    id: '0',
  },
  {
    name: 't2',
    age: 12,
    id: '1',
  },
  {
    name: 't3',
    age: 22,
    id: '2',
  },
];

uuidv4

uuidv4(); // '4839e86e-252f-4571-9982-351cd98cc875'

validObj

const a = {
  name: 't1',
  age: 18,
  email: '[email protected]',
  t1: '',
  t2: null,
  t3: undefined,
};

validObj(a);

output:

{name: 't1', age: 18, email: '[email protected]', t1: ''}

watermark

watermark({
  container = document.body,
  width = '220px',
  height = '200px',
  textAlign = 'center',
  textBaseline = 'middle',
  font = '20px microsoft yahei',
  fillStyle = 'rgba(202,202,202,0.4)',
  content = '请勿外传',
  rotate = '-30',
  zIndex = 1000,
});

wrapPromise

const {read} = wrapPromise(promiseFn);

const result = read();