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 🙏

© 2025 – Pkg Stats / Ryan Hefner

jmw

v0.0.0-alpha.0

Published

JMW 更全面的前端容器,支持axios/fly.io/fetch/uni.request等请求库。

Readme

jmw

JMW更全面的前端容器,支持axios/fly.io/fetch/uni.request等请求库。

Use

Use npm/yarn/pnpm

pnpm add jmw

Example

Use jmw

  • jmw.config
// jmw
import { AxiosAdapter, defineConfig, RequestIoError } from 'jmw';
// Axios
import axios, { AxiosResponse } from 'axios';
// Router
import router from '@/router';
// Message
import { Message } from 'x-next';

export default defineConfig<AxiosResponse>({
  /**
   * Http Client Adapter
   * 请求库适配器,默认提供AxiosAdapter
   */
  ADAPTER: AxiosAdapter,
  /**
   * Http库
   * 例如 axios/fly.io/uni.request...
   */
  HTTP_CLIENT: axios,
  /**
   * 接口映射
   * @description 绑定key-val, 在使用request('app.login')即可发起请求,有助于接口关系管理
   */
  API_MAP: {
    'app.login': ['/api/account/login', ['post', 'JSON']],
    'app.logout': ['/api/account/logout', ['post', 'JSON']],
  },
  /**
   * Http BASE_URL 对于允许跨域访问的接口,可以配置指定host,例如'https://dev..com'。
   * 对于有Nginx代理访问的接口,可以留空字符串或者为window.origin
   */
  BASE_URL: import.meta.env.VITE_API_URL,
  /**
   * 采用RESTFul模式
   * 使用后对路由中使用
   * 默认使用RESTFul模式
   * 例如request(['v1/api/resource/<type=doc>/<id>', 'get'], { __type:'image', __id:8888 }),该资源地址会被自动转化为:
   * 'v1/api/resource/image/8888',如果只传入{ __id: 8888 }则转化为'v1/api/resource/doc/8888'
   */
  USE_REST: true,
  /**
   * Content-Type
   * 可选值为 JSON/ FORM_DATA/ BLOB/ ARRAY_BUFFER等, Get为 Query String Parameters
   * 改配置项为全局默认请求Content-Type方式
   */
  CONTENT_TYPE: 'JSON',
  /**
   * 请求自动携带的默认数据
   * Get为Query String Parameters
   * 可选项:通过Headers携带、通过REQUEST_PAYLOAD 和 FORM_DATA(body)进行数据携带
   * 配置为函数时,您可以自由操作
   */
  DEFAULT_DATA: {
    // Headers数据携带
    HEADERS: {
      // 自动携带token
      Authorization: () => {
        const token = sessionStorage.getItem('token')?.replace(/^"|"$/g, '');
        return token ? `Bearer ${token}` : null;
      },
      // 自动携带租户ID
      'Tenant-Id': () => {
        return sessionStorage.getItem('tenantId')?.replace(/^"|"$/g, '') || null;
      },
    },
    // Data(body、query)数据携带
    PAYLOAD: {},
  },
  /**
   * 权限检测
   * @function
   * @param context
   * @description 检测用户是否登录,未登录跳转登录页
   */
  AUTH_CHECK: (context) => {
    console.log('AUTH_CHECK', context);
    return false;
  },
  /**
   * 分页配置
   * @description 配置分页参数,默认为page、pageSize,当请求参数为page、pageSize,可省略配置
   */
  PAGINATION: {
    page: 'current',
    pageSize: 'size',
    defaultValue: {
      page: 1,
      pageSize: 10,
    },
  },
  /**
   * 失败响应数据格式
   * @param msg 异常消息
   * @param code 异常编码
   * @constructor
   */
  FAILED_RESPONSE_DATA: (msg, code) => ({
    code: code,
    msg: msg,
    data: null,
  }),
  /**
   * 请求中间件
   * 自定义请求中间件并处理业务
   */
  REQUEST_MIDDLEWARE: (context, next) => {
    if (context.request.apiMap[0] !== '/api/admin/i18n/info1') {
      // 当执行next方法时就会放行
      return next(context);
    }
    throw new RequestIoError('请求中间件报错', 16000);
  },

  /**
   * 响应中间件
   * 自定义响应中间件并处理业务
   */
  RESPONSE_MIDDLEWARE: (context, next) => {
    try {
      console.log('context-response', context, next);
      if (context?.response?.data && context?.response?.data?.code === 401) {
        localStorage.clear();
        router
          .push({
            name: 'login',
          })
          .then(() => {
            console.log('TOKEN_ERROR', '令牌失效跳转登录页');
            Message.error('令牌失效,请重新登录');
          });
        return next(context);
      }
      // 这里可能是文件流
      // else if (context?.response?.data && context.response?.data?.code !== 0) {
      //   Message.error(context.response.data.msg);
      //   return next(context);
      // }
      else {
        return next(context);
      }
    } catch (e) {
      console.log('响应中间件报错', (e as Error).message);
    }
  },
});
  • Run
// jmw
import { bootstrap } from 'jmw';
import requestIoConfig from '~file path~/jmw.config';

// 启动应用
bootstrap(requestIoConfig);
  • Request
// jmw
// request 请求函数
// transformer 转换器
// pagination 分页构造器,再配置文件中可设置默认值和对应的page、pageSize的key
import { request, transformer, pagination } from 'jmw';

// 发起请求
// request<response data type>(apiMap, data, headers, extra)
// response data type - response.data类型
// apiMap - api映射 - ['接口', 请求方法|[请求方法,content-type], 是否返回为respone<默认返回response.data>, 是否自动携带数据<默认自动携带>]
// data - 请求的数据(若使用REST方式则自动替换插入值)
// 例如request(['v1/api/resource/<type=doc>/<id>', 'get'], { __type:'image', __id:8888 }),该资源地址会被自动转化为:
// 'v1/api/resource/image/8888',如果只传入{ __id: 8888 }则转化为'v1/api/resource/doc/8888'
// headers - 请求附加头
// extra - 额外插入的数据,例如:如果使用axios,则可包含其额外插入的数据,例如:{ withCredentials: true, timeout: 8000 }
const query = await request<{ status: boolean; data: any }>(['/api/i18n', 'get']);
// pagination(5, 20) 插入分页对象,默认为page=1, pageSize=10,参考配置文件可设置所需值
const post = await request<{ status: boolean; data: any }>(['/api/i18n'], {...pagination(5, 20), name: 'tiktok'}, { swsse: md5(hash) }, { timeout: 8000 });
// 转换器,将对象、数组转换成需要的数据再返回
const data = transformer<any>([{ a: 123 }], (data) => {
		return {
			a: data.a * 1,
			b: data.b * 2,
			c: data.c * 3,
			d: data.d * 4,
			f: data.a * 5,
		};
	});