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 源码

相关推荐
uhakadotcom5 小时前
入门教程:如何编写一个chrome浏览器插件(以jobleap.cn收藏夹为例)
前端·javascript·面试
捡芝麻丢西瓜5 小时前
SPM 之 混编(OC、Swift)项目保姆级教程(Swift Package Manager)
前端
我是天龙_绍5 小时前
cdn是个啥?
前端
南雨北斗5 小时前
VSCode三个TS扩展工具介绍
前端
若无_5 小时前
了解 .husky:前端项目中的 Git Hooks 工具
前端·git
ze_juejin5 小时前
前端发送语音方式总结
前端
给月亮点灯|5 小时前
Vue3基础知识-Hook实现逻辑复用、代码解耦
前端·javascript·vue.js
Simon_He5 小时前
一款适用于 Vue 的高性能流式 Markdown 渲染器,源自我们的 AI 聊天机器人
前端·vue.js·markdown
顽强d石头5 小时前
v-model与.aync的区别
前端·javascript·vue.js
Hilaku5 小时前
我为什么认为 CSS-in-JS 是一个失败的技术?
前端·css·前端框架