Form表单和Yaml转换的优雅实现,支持保留注释

在一些云原生相关的开发需求中,经常会遇到Form表单和Yaml互转的问题,比如下面这个图:

可以通过表单修改Yaml中的部分字段,比如在表单中修改了名称和namespace后切换到Yaml,需要将修改的值更新到Yaml中,这里通常会遇到几个问题:

  • 如果Yaml中有注释,在json转到Yaml后,Yaml中的注释会丢失
  • Form表单中虽然只有2个元素,但是Form表单的json数据必须包含全部信息,否则转为Yaml时丢失了部分信息
  • Yaml不能像Form表单那样进行数据格式校验

现有的Yaml相关库,都只能解决json和Yaml互转问题,而且不能保留注释,为此开发了form2yaml.js。

form2yaml 源码

Form2Yaml

实现Form表单和Yaml数据的转换。

Form2Yaml支持以下特性

  • 在转换中保留Yaml注释
  • 像校验表单(validate)那样校验Yaml数据
  • 支持Form的key与Yaml的key映射

安装

shell 复制代码
npm install form2yaml

使用示例

构造Form2Yaml对象,从Yaml获取JSON

首先通过new 构造Form2Yaml对象实例,构造函数第一个参数为yaml默认内容,第二个参数为options

javascript 复制代码
import Form2Yaml from 'form2yaml';
let yaml = `
 meta:
   name: test  #注释
   namespace: default
 `;
const form2Yaml = new Form2Yaml(yaml);

//根据yaml获取json
console.log(form2Yaml.getJson());
//  {
//    "meta": {
//      "name": "test",
//      "namespace": "default"
//    }
//  }

通过调用form2Yaml.getJson()方法,将yaml数据转为json数据。

有时yaml的key和表单的key并不一致,比如上述示例中的 meta.name,在表单中可能key为name,,可以通过指定keyMap来设置formKey和yamlKey的映射关系。

javascript 复制代码
import Form2Yaml from 'form2yaml';
let yaml = `
 meta:
   name: test  #注释
   namespace: default
 `
const form2Yaml = new Form2Yaml(yaml, {
    keyMap:{
        name: 'meta.name'
    }
});

//根据yaml获取json
console.log(form2Yaml.getJson())
//  {
//    "name": "test",
//  }

设置keyMap后,调用form2Yaml.getJson()默认只返回keyMap指定的字段,如果要返回全部数据,需要这么调用 form2Yaml.getJson('all')

javascript 复制代码
let yaml = `
 meta:
   name: test  #注释
   namespace: default
 `
const form2Yaml = new Form2Yaml(yaml, {
    keyMap:{
        name: 'meta.name'
    }
});
console.log(form2Yaml.getJson('all'))
//  {
//    "name": "test",
//    "meta": {
//      "namespace": "default"
//    }
//  }

原本yaml中的meta.name属性现在映射到了name属性,其他没有设置keyMap的属性,保持原状。

根据表单数据更新YAML

通过form2Yaml.setJson(jsonData)可以修改yaml数据,通过form2Yaml.getYaml()可以获取修改后的yaml数据。

javascript 复制代码
  const yaml = `
 meta:
   name: test  #注释
   namespace: default
 `;
const form2Yaml = new Form2Yaml(yaml);

form2Yaml.setJson({
    meta: {
        name: 'newName'
    }
})
console.log(form2Yaml.getYaml())
// meta:
//   name: newName  #注释
//   namespace: default

在上述示例中,只修改了meta.name的值,可以看到,新的yaml中保留了注释,且meta.namespace未发生变化。

如果你期望没有传递 meta.namespace就认为应该修改为空值,则需要设置option.ignoreMissing=false。

javascript 复制代码
const yaml = `
 meta:
   name: test  #注释
   namespace: default
 `;

// 设置ignoreMissing为false
const form2Yaml = new Form2Yaml(yaml, {
    ignoreMissing: false
});

form2Yaml.setJson({
    meta: {
        name: 'newName'
    }
})
console.log(form2Yaml.getYaml())
//打印的数据中没有了meta.namespace
// meta:
//   name: newName  #注释

在上述示例中,没有传递meta.namespace,或者认为meta.namespace为undefined,修改后的yaml中将会删除meta.namespace字段,如果你想让某个字段在空值时还保留在yaml中,可以设置每个字段的空值模式emptyMode。

javascript 复制代码
const yaml = `
 meta:
   name: test  #注释
   namespace: default
 `;
const form2Yaml = new Form2Yaml(yaml, {
    emptyMode: {
        'meta.namespace': 'retain'
    }
});

form2Yaml.setJson({
    meta: {
        name: 'newName',
        namespace: undefined
    }
})
console.log(form2Yaml.getYaml())
// meta:
//   name: newName  #注释
//   namespace:

在将meta.namespace空值模式设为'retain'后,即使meta.namespace=undefined,依然在yaml中保留namespace字段。

setJson依然支持keyMap配置:

javascript 复制代码
const yaml = `
 meta:
   name: test  #注释
   namespace: default
 `;
const form2Yaml = new Form2Yaml(yaml, {
    keyMap: {
        name: 'meta.name'
    }
});

form2Yaml.setJson({
    name: 'newName',
})
console.log(form2Yaml.getYaml())
// meta:
//   name: newName  #注释
//   namespace: default

更新yaml数据

调用setYaml(newYaml)修改yaml数据。

javascript 复制代码
const yaml = `
 meta:
   name: test  #注释
   namespace: default
   age: NaN
 `;
const form2Yaml = new Form2Yaml(yaml);

const newYaml = `
 meta:
   name: newName  #注释
   namespace: default
 `;

form2Yaml.setYaml(newYaml);

yaml校验

javascript 复制代码
const yaml = `
 meta:
   name: test  #注释
   namespace: default
   age: NaN
 `;
const form2Yaml = new Form2Yaml(yaml, {
    rules: {
        'meta.age': [{pattern: /^\d+$/, message: '年龄必须为数字'}]
    }
});

form2Yaml.validate().then(_ => {
    console.log('校验通过')
}).catch(err => {
    console.log('校验失败')
    console.log(err)
})

如果暂时还没有遇到表单和yaml互转场景,记得先收藏哦,零star新项目,不收藏你可找不到哈哈哈

form2yaml 源码

相关推荐
乔旭伟2 小时前
Vben3 中后台表格封装实战:useVbenVxeGrid 的全局收敛与七个坑
前端·anti-design-vue·1024程序员节
鶴哥只手遮天2 小时前
jQuery 4.0 源码架构与工程实践-第 10 章 尺寸、几何与显隐
前端·javascript·jquery
Mia_墨黎2 小时前
2026 Windows 11 终端美化完全指南
前端·后端
用户1880687493522 小时前
戴着 Rokid 接成语:用 AIUI 做一局有提示、有复盘的“接着说”
前端
Sakura_j_h_2 小时前
Three.js 单文件离线机械臂工作台:爆炸图、透明外壳与剖面
前端·机械臂·webgl·three.js·1024程序员节·esbuild
计算机魔术师4 小时前
管谷歌的不是Pichai一个人,是一整层AI智能体
前端
米米商聊4 小时前
图标能点,按钮就可用了吗?键盘、名称与收藏状态
前端·javascript
Younglina4 小时前
三个晚上,我和 WorkBuddy 做了个生图网站
前端·后端·ai编程
xy34535 小时前
Axure 9.0 内联框架加载方式
前端·ui·html·axure·原型·产品设计
陈随易6 小时前
副业搞钱点子之收入查看器
前端·后端