Check and validate JSON schema (#1509)

* Validate json

* wip: gh workflow test

* wip: added workflow for JSON validation

* Schema Improved.

* Improved Workflow and Schema check for JSON files

* Fixed JSON Schema

* Fixed typo

* Removed auto generated file

* updated required fields in chainSchema

* updated chain schema

* removed `network` from README.md example

* improved schemaCheck script

* Matching ChainID with file name schema.
This commit is contained in:
Ashutosh Kumar 2022-08-28 15:55:46 +05:30 committed by GitHub
parent a3cd16b7a7
commit bf8ce68096
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 298 additions and 5 deletions

24
.github/workflows/validate_json.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: Check JSON Schema
on:
push:
pull_request:
jobs:
validate_json:
runs-on: ubuntu-latest
steps:
- name: Check out repo
uses: actions/checkout@v2
- uses: actions/cache@v2
name: Configure npm caching
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/workflows/validate_json.yml') }}
restore-keys: |
${{ runner.os }}-npm-
- name: Run JSON Validation
working-directory: ./tools
run: |-
npm install
node schemaCheck.js

114
tools/package-lock.json generated Normal file
View File

@ -0,0 +1,114 @@
{
"name": "tools",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"devDependencies": {
"ajv": "^8.11.0"
}
},
"node_modules/ajv": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/epoberezkin"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"node_modules/json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"node_modules/punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"dependencies": {
"punycode": "^2.1.0"
}
}
},
"dependencies": {
"ajv": {
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
"integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"json-schema-traverse": "^1.0.0",
"require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
}
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"json-schema-traverse": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
"require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"dev": true
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
}
}
}
}

5
tools/package.json Normal file
View File

@ -0,0 +1,5 @@
{
"devDependencies": {
"ajv": "^8.11.0"
}
}

View File

@ -2,18 +2,20 @@
* This removed `network` param from all the chain files * This removed `network` param from all the chain files
* Since this is the only tool here, it is here in index.js * Since this is the only tool here, it is here in index.js
*/ */
const fs = require('fs'); const fs = require('fs');
const { exec } = require('child_process');
const chainFiles = fs.readdirSync('../_data/chains/'); const chainFiles = fs.readdirSync('../_data/chains/');
for(const chainFile of chainFiles){ for (const chainFile of chainFiles) {
const fileLocation = `../_data/chains/${chainFile}` const fileLocation = `../_data/chains/${chainFile}`
const fileData = fs.readFileSync(fileLocation,'utf8') const fileData = fs.readFileSync(fileLocation, 'utf8')
const fileDataJson = JSON.parse(fileData) const fileDataJson = JSON.parse(fileData)
if(fileDataJson.network){
if (fileDataJson.network) {
delete fileDataJson.network delete fileDataJson.network
fs.writeFileSync(fileLocation, JSON.stringify(fileDataJson, null, 2)) fs.writeFileSync(fileLocation, JSON.stringify(fileDataJson, null, 2))
} }
} }
// TODO: Run `npx prettier --write --ignore-unknown _data`from Project Directory // Note:
// Run `npx prettier --write --ignore-unknown _data`from Project Directory

View File

@ -0,0 +1,123 @@
{
"$schema": "http://json-schema.org/schema#",
"title": "EIP155 Chain Data",
"type":"object",
"required": ["name","shortName","chain","chainId","networkId","rpc","faucets","infoURL","nativeCurrency"],
"properties": {
"name":{
"type":"string",
"description": "Name of the Network"
},
"shortName":{
"type":"string"
},
"title":{
"type":"string",
"description": "Optional title for the Network"
},
"chain":{
"type":"string",
"description": "Name of the Network"
},
"icon":{
"type":"string",
"description": "Icon type"
},
"rpc":{
"type":"array",
"items":{
"type":"string"
}
},
"faucets":{
"type":"array",
"items":{
"type":"string"
}
},
"nativeCurrency":{
"type":"object",
"properties": {
"name":{
"type":"string",
"description":"Name of the Native Currency"
},
"symbol":{
"type":"string",
"description":"Symbol of the Native Currency"
},
"decimals":{
"type":"number",
"description":"Decimal points supported"
}
}
},
"infoURL":{
"type":"string",
"description": "infoURL"
},
"chainId":{
"type":"number",
"description": "Chain ID of the Network"
},
"networkId":{
"type":"number",
"description": "Network ID of the Network"
},
"slip44":{
"type":"number",
"description": "Slip44 of the Network"
},
"ens":{
"type":"object",
"properties": {
"registry":{
"type":"string"
}
}
},
"explorers":{
"type":"array",
"items":{
"type":"object",
"properties": {
"name":{
"type":"string"
},
"url":{
"type":"string"
},
"standard":{
"type":"string"
}
}
}
},
"parent":{
"type":"object",
"properties": {
"type":{
"type":"string"
},
"chain":{
"type":"string"
},
"bridges":{
"type":"array",
"items": {
"type":"object",
"properties":{
"url": {
"type":"string"
}
}
}
}
}
},
"status":{
"type":"string"
}
},
"additionalProperties": false
}

25
tools/schemaCheck.js Normal file
View File

@ -0,0 +1,25 @@
const fs = require('fs');
const Ajv = require("ajv")
const ajv = new Ajv()
const schema = require('./schema/chainSchema.json')
const chainFiles = fs.readdirSync('../_data/chains/');
const filesWithErrors = []
for(const chainFile of chainFiles){
const fileLocation = `../_data/chains/${chainFile}`
const fileData = fs.readFileSync(fileLocation,'utf8')
const fileDataJson = JSON.parse(fileData)
const chainIdFromFileName = chainFile.match(/eip155-(\d+)\.json/)[1]
if(chainIdFromFileName != fileDataJson.chainId){
throw new Error(`File Name does not match with ChainID in ${chainFile}`)
}
const valid = ajv.validate(schema, fileDataJson)
if(!valid) {
console.error(ajv.errors)
filesWithErrors.push(chainFile)
}
}
if(filesWithErrors.length > 0){
throw new Error(`Invalid JSON Schema in ${filesWithErrors.length} files at ${filesWithErrors.join(",")}`)
}