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

ajv-extends

v1.0.0

Published

ajv extends

Downloads

1

Readme

ajv-extends

Ajv 延伸扩展。Ajv 是基于 json-schema / JTD 对数据进行验证的一个辅助库。其功能是能满足大部分的数据验证的场景的,但这个实际运用却很生草。

首先,Ajv 将初始化和错误处理(多语言),进行了分离,使得实际调用的代码异常臃肿。

如果你需要在项目环境中引用诸如 ajv-formats ajv-i18n ,那你的代码可能会是如下:

import Ajv from 'ajv';
import addFormats from 'ajv-formats';
import localize_zh from 'ajv-i18n/localize/zh';

const ajv = new Ajv();

addFormats(ajv);
ajv.addKeyword({
  keyword : 'someKeyword',
  validate: () => true,
});
// 这里可能还有很多你自己项目里的扩展


// 到使用:
const schema = {
  type      : 'object',
  properties: {
    // ....
  },
  required  : [
    // ...
  ]
}
const validate = ajv.compile(schema);

const data = {};
const valid = validate(data);

if (!valid) {
  // 将错误信息本地化
  localize_zh(validate.errors);
}

其次,如果你项目中需要使用 react-hook-form,以及 @hookform/resolverreact-hook-form 出品的包含市面常用的 js validator 的 resolver),就会发现,@hookform/resolver/ajvResolver 是在其内部闭环的,你无法在这过程中加入其他的 ajv 扩展或者多语言本地化的处理。

可以参考这个文件:@hookform/resolver/ajv.ts

再次,ajv-i18n 的汉化,仍有需要不完善的地方,大体可以用,但是总需要在实际项目进行拦截和优化。

最后的最后,往往当我们在实际项目中添加一种 format / keyword,可能希望他能被更简单的在下一个项目重用起来,而一种 format / keyword 往往是和 localize 紧密结合的,所以需要有一个更简易的环境去使用 ajv,这也是创建这个项目的目的。

Ajv 延伸,意在由你自己决定如何扩展延伸,项目本身只提供一个简易的粘合作用,将 Ajv 的一些常用方法重新调整调用的方式,以便于人类理解使用。

主要内容

ajv.ts

该部分主要提供了一个全局简易创建和使用 Ajv 实例的快捷方式。

import { createAjv, ajv } from 'ajv-extends';

createAjv 创建一个全局统一的创建 Ajv 实例的方法

import addFormats from 'ajv-formats';
import localize_zh from 'ajv-i18n/localize/zh';

// 全局的 ajv 实例创建句柄
// 这样,通过 ajv 创建的所有 ajv 实例,都会自动套用 use / useLocalize 所添加的扩展和本地化
export const ajv = createAjv()
  // 加入扩展
  .use((ajvInstance, { useLocalize }) => {
    // 每次创建 ajv 实例的时候会执行
    addFormats(ajvInstance);
    // 其他扩展
    ajvInstance.addKeyword({
      keyword : 'someKeyword',
      error: {
        message: () => 'xxx',
        // => 需要将这个 keyword 的 params 进行传递,才能在本地化的时候得到这个 keyword 相应的 params
        params: (cxt) => cxt.params,
      },
      validate: () => true,
    });

    useLocalize((errors) => {
      if (!errors || !errors.length) return;
      errors.forEach(err => {
        if (err.keyword === 'someKeyword') {
          err.message = 'xxx' + err.params;
        }
      })
    });
  })
  // 本地化
  // 只在验证时发生错误时执行
  .useLocalize(localize_zh)
  // 创建 ajv 实例时候的默认 options
  .setOptions({ allErrors: true })
;

// 创建一个 ajv 实例
const localAjv = ajv();

// 1. 创建一个 ajv 实例,
// 2. 并 compile schema,
// 3. 然后执行 validate
// 默认模式
const { valid, errors } = ajv.validate(data, schema);

// throw error 模式
try {
  ajv.validate(data, schema, true);
} catch (err) {
  // TS 将所有 err 变为 unknown 类型,所以需要自行 detect
  if (ajv.isValidationError(err)) {
    console.log(err.errors);
  }
}

ajv 为默认创建的一个全局单例 export const ajv = createAjv() ,主要用于给一些小项目直接使用(比如有些时候真的连单独创建一个 ajv 的文件都懒的时候)。但不推荐这样用(不使用他,可以不导出这个 ajv)。

schema.ts

该部分主要为快捷创建 schema 的方法封装,目前只提供 object 类型的快捷定义

import { schemaObject } from 'ajv-extends';

schemaObject({
  key: { type: 'string' },
}, ['key'])

// 支持指定泛型
// 解除了 ajv 默认的 properties 锁定的设定,即:
// 1. 强制限定 Type.field 的类型,必须和 properties 的类型强关联(实际应用中,验证器往往总是要包含更多情况)
// 2. 如果指定 Type.field 为 ? (即可能为 undefined),会强制要求对应的 properties 声明中增加 nullable
// 3. required 声明也必须限定在 Type 字段内。
// 以上三方面的限制皆去除,并且能自动根据 Type 进行代码提示。
type Type = {
  field: string,
}
schemaObject<Type>(
  // properties 声明
  {
    field: { type: 'string' },
  },
  // required 声明
  ['field'],
  // additionalProperties
  true,
  // 其他 schema 属性
  {
    patternProperties: {
      
    },
    // ....
  }
)