Skip to content

fix fufuture json

fix fufuture json #219

Workflow file for this run

name: Validate JSON Files
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
validate-json:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Install jq
run: sudo apt-get update && sudo apt-get install -y jq
- name: Install dependencies
run: |
npm init -y
npm install ajv ajv-cli glob
- name: Validate JSON syntax
run: |
# Find all JSON files and validate syntax
find . -name "*.json" -not -path "./node_modules/*" -not -path "./.git/*" | while read file; do
echo "Validating syntax of $file"
if ! cat "$file" | jq empty; then
echo "❌ Invalid JSON syntax in $file"
exit 1
else
echo "✅ Valid JSON syntax in $file"
fi
done
- name: Validate required fields
run: |
# Create validation script
cat > validate_fields.js << 'EOF'
const fs = require('fs');
const path = require('path');
const { glob } = require('glob');
// Define required fields here
const REQUIRED_FIELDS = [
'name', 'description', 'categories', 'addresses', 'links'
];
// Load categories from file
let CATEGORIES = [];
try {
const categoriesData = JSON.parse(fs.readFileSync('./categories.json', 'utf8'));
CATEGORIES = categoriesData.categories;
console.log(`📋 Loaded ${CATEGORIES.length} valid categories from categories.json`);
} catch (error) {
console.log(`❌ Error loading categories file: ${error.message}`);
process.exit(1);
}
async function validateFiles() {
const jsonFiles = await glob('**/*.json', {
ignore: ['categories.json', 'node_modules/**', '.git/**', 'package*.json']
});
let hasErrors = false;
for (const file of jsonFiles) {
console.log(`Checking required fields in ${file}`);
try {
const content = JSON.parse(fs.readFileSync(file, 'utf8'));
const missingFields = REQUIRED_FIELDS.filter(field => !(field in content));
if (missingFields.length > 0) {
console.log(`❌ ${file} is missing required fields: ${missingFields.join(', ')}`);
hasErrors = true;
} else {
console.log(`✅ ${file} has all required fields`);
}
// Validate categories field
if (content.categories) {
if (!Array.isArray(content.categories)) {
console.log(`❌ ${file}: 'categories' field must be an array`);
hasErrors = true;
} else {
const invalidCategories = content.categories.filter(category =>
!CATEGORIES.includes(category)
);
if (invalidCategories.length > 0) {
console.log(`❌ ${file} contains invalid categories: ${invalidCategories.join(', ')}`);
console.log(` Valid categories must be from: ${CATEGORIES.join(', ')}`);
hasErrors = true;
} else {
console.log(`✅ ${file} has valid categories`);
}
}
}
// Validate addresses field
if (content.addresses) {
if (typeof content.addresses !== 'object' || Array.isArray(content.addresses)) {
console.log(`❌ ${file}: 'addresses' field must be an object`);
hasErrors = true;
} else {
const invalidAddresses = [];
for (const [key, address] of Object.entries(content.addresses)) {
// Check if it's a valid Ethereum address (0x + 40 hex characters)
const isValidAddress = typeof address === 'string' &&
/^0x[a-fA-F0-9]{40}$/.test(address);
if (!isValidAddress) {
invalidAddresses.push(`${key}: "${address}"`);
}
}
if (invalidAddresses.length > 0) {
console.log(`❌ ${file} contains invalid Ethereum addresses:`);
invalidAddresses.forEach(addr => console.log(` ${addr}`));
console.log(` Valid format: 0x followed by 40 hexadecimal characters`);
hasErrors = true;
} else {
console.log(`✅ ${file} has valid Ethereum addresses`);
}
}
}
} catch (error) {
console.log(`❌ Error reading ${file}: ${error.message}`);
hasErrors = true;
}
}
if (hasErrors) {
process.exit(1);
}
}
validateFiles();
EOF
# Run validation
node validate_fields.js