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

tools2

v1.9.6

Published

tools

Downloads

721

Readme

工具库

正在完善中……

const str = 'https://qshfu.com/lib?v=1.0'
str.before('?') // 'https://qshfu.com/lib'
str.before('//', '?') // ['https:', 'qshfu.com/lib']
'https://qshfu.com/lib?v=1.0'.after('?') // 'v=1.0'

random() // 6
random(10, 29) // 18
random(10, 199) // 123

'sum(1+1+sum(2+3))+sum(2+4)'
        .replace2(/sum\([^]*?\)/g, {m: 'sum', '*': /\+/g})
        // 'm(1*1*sum(2*3))+m(2*4)'
        
'sum(1+1+sum(2+3))+sum(2+4)'
        .replace3({prev: 'sum', start: '(', end: ')'}, {m: 'sum', '*': /\+/g})
        // 'm(1*1*sum(2*3))+m(2*4)'
        
[1, 2, 3, 4, 5].forEachReverse(i => i === 2 ? false : console.log(i)) // 5,4,3
[1, 2, 3, 4, 5].forEach2(i => i === 4 ? false : console.log(i)) // 1,2,3

const data = {}, key = {}
data.$set(key, '123')
data.$get(key) // '123'

isEmpty({}) // true
isEmpty({}, {qwe: 123}) // false

new Date('2022/01/01').format('yyyy-MM-dd 周D')
// '2022-01-01 周六'

isObject(undefined) // false

class StatusEnum extends Enum {
    RESOLVE = 1
    REJECT
    
    constructor() {
    
        super().init()
    }
}

const status = new StatusEnum()

status[status.REJECT] // 'REJECT'

class Main extends Singleton {

    constructor() {

        super()
    }
}

new Main() === new Main() // true
// 使用create可能会创建失败,推荐使用异步版本createId
let id
id = create()
id = create()
id = create()
id = await createId()
id = await createId()
id = await createId()
// 递归删除文件夹
rmdir('./tmp')
// 解析url参数
u2o('localhost?qwe=123&asd=456&code') // { qwe: '123', asd: '456', code: 'code' }
// 简单的加解密
const key = createKey('abc123')
const data = encrypt({name: '张三', age: '21'}, key).toString()
console.log(decrypt(data, key))
// 或者
const data = Buffer.from(JSON.stringify({name: '张三', age: 21}))
const key = Buffer.from('abc123')
console.log(XOR(data, key).toString())
console.log(XOR(data, key).toString())
// 自定义的JWT
const sKey = Buffer.from('456')
const cKey = Buffer.from('123')
const data = {name: '张三', age: 21}
console.log(fromJWT(toJWT(data, sKey, cKey), sKey))

实例文件test.mjs

运行指定版本

目录结构

folder ┳ 0.1 ┳ index.mjs // 入口、必需
       ┃     ┗ ...
       ┣ ...
       ┣ 2.1 ┳ index.mjs // 入口、必需
       ┃     ┗ ...
       ┣ node_modules // 共用库
       ┗ package.json
// ./index.mjs 入口文件,需要和版本文件夹同目录,版本文件夹内一定要有index.mjs文件
// import {} from "tools2/version.mjs"; // 没有指定版本会在目录中通过文件夹名找最新版本
import {} from "tools2/version.mjs?v=2.0&e=index.mjs";
// import {} from "tools2/version.mjs?version=2.0&entry=index.mjs";

轻量级的代理工具

import {createProxy} from 'min-proxy'

createProxy({
    map: {
        '/target': 'http://domain/',
        '/': '/dir',
        'http://domain2/': 'http://domain3/'
    },
    port: 80,
    httpsOptions: {
        key,
        cert
    },
    preReq: (req, res) => false,
    preRes: (req, res) => false,
})

封装express

import {Base, Express} from "tools2/router.mjs";

const app = new Express({
    port: 8080,
    callback: () => console.log('running...')
})

class Test extends Base {

    cache = 0
    // 当提供3个参数的函数实现时则加入认证队列
    AUTH(req, res, next) {

        console.log(req.headers)

        next()
    }

    get path() {

        return super.path + '/test'
    }
}

class Admin extends Test {

    id = 0

    AUTH(req, res, next) {

        console.log(req.cookies)
        console.log(req.query)

        next();
    }

    async GET(req, res) {

        res.end(this.view) // new Express({root: 'wwwroot'}) 与 root 参数有关 
        
        // 服务器端渲染,每次访问都会重新计算渲染,会增加服务器负担,建议权限控制较高使用不频繁的场景使用
        // this.render(this.view, {})
        // /<script server>[^]*?<\/script>/g 支持服务器端脚本 <script server>write(`<b>hello~${data.qwe}</b>`)</script>
        // /{\/[^]*?}/g 支持服务器端引入 {/com/head.html}
    }

    async POST(req, res) {

        await this.queue() // 必须和this.pass()成对使用

        res.end(`id: ${this.id++}`)

        this.pass() // 必须和this.queue()成对使用
    }

    get path() {

        return super.path + '/admin'
    }
}

app.use((req, res, next) => res.setHeader('Access-Control-Allow-Origin', '*') && next())

app.use(Admin)
// app.use(new Admin())
// app.load('./lib')

将mjs的库打包

*重要

1、打包时候node版本要对应

2、使用--experimental-vm-modules模式

> node --experimental-vm-modules index.mjs

结构

root ┬ lib1 ┬ index.mjs
     │      ├ data.json
     │      └ ...
     ├ index.mjs // 编译后生成
     └ ...

实例

import {build} from 'tools2/module.mjs'

build('lib1', 'index') // 打包

import {} from './lib1/index.mjs' // 开发模式

import {} from './index.mjs' // 生产模式,打包后

支持开发代码

let env = 'prod'
// IF DEV
env = 'dev'
// END DEV
console.log(env) // 开发模式:prod;生产模式(打包后):prod

Note:

class Base {
    /**
     * 定义成员函数,制定规则
     * @param {any[]} arg
     */
    func(...arg) {

        if (this === undefined) return

        // init

        this.func = (...arg) => {

            // todo
        }

        this.func(...arg)
    }
    /**
     * 定义成员变量,提供工具
     * @param {String} key
     * @param {Function} init
     */
    define(key, init) {

        Object.defineProperty(this, key, {

            get() {

                const value = init()

                Object.defineProperty(this, key, {

                    get() {

                        return value
                    }
                })

                return value
            },

            configurable: true
        })
    }
}

硬件信息

import {cpu, mem, sys, node, disk} from 'tools2/info.mjs'

console.log(cpu()) // 处理器信息
console.log(mem()) // 内存信息
console.log(sys()) // 系统信息
console.log(node()) // node版本信息
console.log(disk()) // 硬盘信息

mysql ssh 连接

import Query from 'tools2/mysql2ssh2.mjs'

const query = new Query({...}, {...})

query`SELECT * FROM t_test`.then(...)

query.close()

微服务功能

基于tcp或者udp连接

tcp支持集群

import cluster from 'cluster'
import {cpus} from 'os'

if (cluster.isPrimary) {

    cpus().forEach(() => cluster.fork())

} else {

    // todo

    console.log(`Worker ${process.pid} started`)
}

udp

import {udpService, tcpService} from './index.mjs'
const pools = {
    s: {test: 'localhost:9000/test'}
}
// 9000端
const s = udpService(pools, {port: 9000, callback(path, data, next) {

    next('9000')
}})
// s.close()
// 9001端
const map = new Map
map.set('/test', data => new Promise((resolve, reject) => reject('9001')))
udpService(pools, {port: 9001, map}).s.test().then(r => console.log(r.toString())) // '9000'

tcp

const pools = {
    s: {test: 'localhost:9000/test'}
}
// 9000端
const map = new Map
map.set('/test', data => '9000')
const s = tcpService(pools, {port: 9000, map})
// s.close()
// 9001端
tcpService(pools, {port: 9001, callback(path, data, next) {}})
    .s.test().then(r => assert.equal(r, '9000')) // '9000'