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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wujibase/data-schema-core

v1.0.46

Published

```js import { DataStub, DataSchema, getPatchedDataSchema, getDefaultValue } from "@wujibase/data-schema-core" import "@wujibase/data-schema-core/lib/presets/vue" // 如果你使用 Vue 开发应用,请务必引入这个先

Readme

DataSchema Core

import { DataStub, DataSchema, getPatchedDataSchema, getDefaultValue } from  "@wujibase/data-schema-core"
import "@wujibase/data-schema-core/lib/presets/vue"    // 如果你使用 Vue 开发应用,请务必引入这个先

// 然后写代码

常用用法

1. 补全 DataSchema

DataSchema 里有灵活的 $ref 机制,可以描述无限嵌套的对象,但是这会使得解析工具变得困难。

先看一个例子

const rawSchema = {
  type: 'object',
  title: '神奇嵌套对象',
  fields: [
    { id: 'name', type: 'string' },
    { id: 'extra' /* , type: 漏了 */, required: false },
    { id: 'children', type: 'array', items: { $ref: '#' } },
  ],
}

可以看到上面编写的 DataSchema 描述了一个对象,但是存在奇怪的问题:

  • name 字段没有定义 required
  • extra 字段没有定义 type
  • children 字段是一个数组,但是它的数组项格式,引用了根类型(就是这个整体),是一个循环的类型定义引用:
# 上面的 DataSchema,大概描述的是这样的东西

{
  name: 'foobar',
  extra: '这个字段可能是任意类型',
  children: [       # 这个的数组项,和最外层的数据结构是一样的
    { 
      name: 'sub1',
      children: []
    },
    { 
      name: 'sub2',
      extra: {},
      children: [
        {
          name: '无限嵌套children', 
          children: []
        }
      ]
    },
  ]
}

如果直接使用一开始写的 DataSchema,那肯定是要考虑很多边界情况的。 因此,这个包提供了一个 getPatchedDataSchema 的方法,能够生成一个 补全过的,可能无限嵌套的 新 DataSchema。

const schema = getPatchedDataSchema(rawSchema);

然后你会发现,你拿到了一个自动补全后的完整 DataSchema:

// ...前略
schema.type === 'object'
schema.fields === [
  { 
    id: 'name',
    type: 'string',
    required: true,     // object 的 fields 里,字段的 required 都补全了默认值
  },
  { 
    id: 'extra',
    type: 'any',        // 未定义类型的字段,补全了 type: any    
    required: false,
  },
  { 
    id: 'children',
    type: 'array',
    items: {
      $ref: '#',        // 原来声明的 $ref 还在,
      type: 'object',   // 同时,还补全了 type 信息
      fields: [         // 以及根类型(就是整个 schema 本体)里定义的全部字段
        { ... },
        { ... },
        { ... }         // 然后在这第三个字段里,又无限地自动补全了。
      ]
    },
    required: true,
  }
]

这种被补全过的,具备无限嵌套的 DataSchema,我们叫做 PatchedDataSchema。

现在,你可以安心地读取 PatchedDataSchema 里每一个数据类型的 type、fields、items 等信息了, 不需要担心默认值缺失、$ref 等问题。

注意,这个 PatchedDataSchema 因为可能有无限嵌套的情况,因此请不要拿他 JSON.stringify, 仅在代码中需要时,通过 getPatchedDataSchema 生成即可。

2. 生成默认值

const ans = getDefaultValue({
  type: 'object',
  fields: [
    { id: 'foo', type: 'string' },
    { id: 'bar', type: 'number' },
    { id: 'baz', type: 'boolean', required: false },
  ]
})

// ==> { foo: "", bar: 0 }

其实 getDefaultValue 还有第二参数,可以传入一个配置对象,支持下面参数:

  • useLorem: boolean,默认字符串和数字会使用空值,可设置这个为 true 则使用 Lorem Ipsum
  • includeOptional: boolean,默认会抛弃 required 为 false 的 field,如果需要的话,可将这个选项开启
  • mockArrayItems: number,默认对于所有 array 都是生成空数组,这里可指定条数,可生成一些数组项(如果存在无限嵌套的情况,请勿开启)
  • ignoreCondition: boolean,默认在生成对象时会遵守字段的 condition 并选择性剔除一些字段,将此设置为 true 则保留全部字段

3. 从其他格式,生成 DataSchema

| | | | 模块 | 用例覆盖 | 需要额外安装的 npm 包 |---|-|-----|-----|----|--- | JSON Schema | ⇄ | Data Schema | lib/convertor/jsonSchema | ✓ | | Protobuf | → | Data Schema | lib/convertor/protobuf | ✓ | protocol-buffers-schema | JSON Data | → | Data Schema | lib/convertor/jsonData | ✓ | | 无极 FieldInfo | ⇄ | Data Schema | lib/convertor/wuji | |

使用方式举例:

⚠️ 注意:这里转化出来的 DataSchema,不是 PatchedDataSchema。这两者的区别,详见上文《补全 DataSchema》

import { fromJsonData } from '@wujibase/data-schema-core/convertor/jsonData';
import { fromJSONSchema, toJSONSchema } from '@wujibase/data-schema-core/convertor/jsonSchema';

// 从一个实际的数据转化
// 这个方法有第二可选参数,IDE自动补全会告诉你
const schema1 = fromJsonData({
  tags: ['aaa', 'bbb'],
  num: 123.456,
  int: 1234,
  str: 'foobar',
  bool: true,
})

// 从 JSON Schema 转为 DataSchema
const schema2 = fromJSONSchema({
  type: 'object',
  required: ['name'],
  properties: {
    name: { type: 'string' },
    credit_card: { type: 'number', examples: [12345] },
    type: { type: 'number', enum: [1, 2, 3] },
    billing_address: {
      type: 'array',
      items: { type: 'string' },
    },
  },
})

4. DataStub

如果你需要围绕 DataSchema + 实际数据,做一系列的操作, 想将不同的个字段,一个个绑定到不同的地方(比如编辑器组件),同时:

  • 希望绑定到的地方,可以方便的获取当前字段的 schema 信息、上游、下级等
  • 希望数据的读写更安全,不被链路上的 null 和 undefined 坑掉
  • 希望读写行为有统一的、准确的 watch 能力
  • 生成某字段的默认值
  • (如果当前字段是一个 object)获取当前 object 可用 fields(DataSchema 支持定义字段的存在条件)
  • (如果当前字段是有枚举定义的)获取枚举选项(DataSchema 支持定义动态枚举选项)
  • ……

那么,你可以使用 schema + 初始 value,创建一个 DataStub,完成上述操作。并且,通过它还能获取到各个子字段的子 DataStub,如法炮制。

上述场景里需要的信息、能力,都可以在 DataStub 实例中找到。

const schema: DataSchema = {
  type: 'array',
  items: {
    type: 'object',
    fields: [
      { id: 'name', type: 'string' },
      { id: 'code', type: 'number' },
    ],
  },
};

const stub = new DataStub({
  schema,
  value: null, // 初始值为 null
});

console.log(stub.schema); // 获取 schema,输出 Patched DataSchema
console.log(stub.value); // 一开始的初始值是 null
console.log(stub.length); // == 0 数组长度

stub.push({ name: 'xxx', code: 123 }); // 即使整个数据为 null,也可以 push
console.log(stub.value); // 然后就有数据了: [ { name: 'xxx', code: 123 } ]
console.log(stub.length); // == 1

// 子 DataStub 使用示例

const code1 = stub.getStubAtPath('[1].code') // 指向一个不存在的数据实体
console.log(code1.schema)   // 取 schema,输出 { id: 'code', type: 'number', required: true }
console.log(code1.value)    // 取值,虽然数据不存在,但只是输出 undefined,不会报错

code1.value = 1234    // 为不存在的路径( [1].code )赋值
console.log(code1.value)    // 输出 1234
console.log(stub.value);    // 输出 [ { name: 'xxx', code: 123 }, { code: 1234 } ]
console.log(stub.length);   // == 2