High-performance validation library for the Open Filament Database, written in Rust with Python and Node.js bindings.
- JSON Schema Validation — validates filament data against JSON schemas with compiled schema caching
- Logo Validation — checks image dimensions (PNG, JPEG) and validates SVG root elements
- Folder Name Validation — ensures folder names match their JSON content IDs
- Store ID Validation — cross-references store IDs in purchase links
- GTIN/EAN Validation — validates product barcodes
- Missing File Detection — checks for required files at each hierarchy level
- Parallel Processing — multi-threaded validation using Rayon
pip install ofd-validatorRequires Python 3.10+. No additional Python dependencies needed (self-contained compiled extension).
Published to GitHub Packages. Add a .npmrc in your project root:
@openfilamentcollective:registry=https://npm.pkg.github.com
Then install:
npm install @openfilamentcollective/ofd-validatorPrebuilt binaries included for Linux (x64, arm64), macOS (x64, arm64), and Windows (x64).
The library exposes standalone functions rather than a class. All functions accept directory paths as strings and return a ValidationResult object.
from ofd_validator import validate_all, validate_json_files, validate_logo_files, validate_folder_names
# Run all validations at once
result = validate_all("data", "stores")
# Or run specific batches
result = validate_json_files("data", "stores")
result = validate_logo_files("data", "stores")
result = validate_folder_names("data", "stores")
# JSON schemas can be in a custom directory
result = validate_all("data", "stores", schemas_dir="schemas")
result = validate_json_files("data", "stores", schemas_dir="schemas")from ofd_validator import validate_store_ids, validate_gtin_ean, validate_required_files
from ofd_validator import validate_logo_file, validate_folder_name
result = validate_store_ids("data", "stores")
result = validate_gtin_ean("data")
result = validate_required_files("data", "stores")
# Single-item validators
result = validate_logo_file("data/BrandX/logo.png", logo_name="logo.png")
result = validate_folder_name("data/BrandX", "brand.json", "id")result = validate_all("data", "stores")
result.is_valid # True if no errors (warnings are OK)
result.error_count # Number of errors
result.warning_count # Number of warnings
result.errors # List of ValidationError objects
# Merge results from multiple runs
combined = ValidationResult()
combined.merge(result_a)
combined.merge(result_b)
# Serialize to dict (for JSON output)
d = result.to_dict()
# {"is_valid": True, "error_count": 0, "warning_count": 0, "errors": [...]}for error in result.errors:
error.level # ValidationLevel.Error or ValidationLevel.Warning
error.level.value # "ERROR" or "WARNING"
error.category # e.g. "JSON Schema", "Logo", "Folder Name"
error.message # Human-readable description
error.path # Optional file path (str or None)const { validateAll, validateJsonFiles } = require('@openfilamentcollective/ofd-validator');
const result = validateAll('./data', './stores', './schemas');
console.log(result.isValid); // boolean
console.log(result.errorCount); // number
console.log(result.warningCount); // number
for (const err of result.errors) {
console.log(`${err.level} [${err.category}]: ${err.message} (${err.path})`);
}Pass file contents directly as strings or Buffers. Useful for CI pipelines, API-fetched data, or server-side validation.
const { validateJsonContent, validateAllContent } = require('@openfilamentcollective/ofd-validator');
const fs = require('fs');
// Single JSON validation
const schemas = {
brand: fs.readFileSync('schemas/brand_schema.json', 'utf-8'),
};
const result = validateJsonContent(
'{"id": "BrandX", "name": "Brand X", "logo": "logo.png"}',
'brand',
schemas,
'data/BrandX/brand.json' // optional label for error messages
);
// Batch validation from in-memory data
const fullResult = validateAllContent({
jsonFiles: [
{ path: 'brand.json', schemaName: 'brand', content: '{"id":"BrandX"}' },
],
logoFiles: [
{ path: 'logo.png', filename: 'logo.png', content: fs.readFileSync('logo.png') },
],
folders: [
{ path: 'data/BrandX', folderName: 'BrandX', jsonContent: '{"id":"BrandX"}', jsonKey: 'id' },
],
storeIds: ['amazon'],
schemas: schemas,
});For the full JS API reference, see docs/js-api.md.
- Rust (stable)
- Python 3.10+ and maturin (for Python bindings)
- Node.js 18+ (for JS bindings)
# Python: build and install into current env
maturin develop --release
# JS: build native addon
cd crates/ofd-validator-js && npm install && npm run build
# Check all crates
cargo check --workspacecargo test --workspaceofd-validator/
├── Cargo.toml # Workspace definition
├── pyproject.toml # Python package config (maturin)
├── crates/
│ ├── ofd-validator-core/ # Pure Rust validation library (no FFI)
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── types.rs # ValidationLevel, ValidationError, ValidationResult
│ │ ├── schema_cache.rs # Compiled JSON schema cache
│ │ ├── util.rs # Constants, helpers
│ │ ├── orchestrator.rs # DataSet + parallel batch validation
│ │ └── validators/ # Individual validator implementations
│ ├── ofd-validator-python/ # PyO3 bindings
│ │ └── src/
│ │ ├── lib.rs # #[pymodule] definition
│ │ ├── types.rs # PyO3 wrapper types
│ │ ├── orchestrator.rs # Python batch validators
│ │ └── validators.rs # Python individual validators
│ └── ofd-validator-js/ # napi-rs bindings
│ ├── src/lib.rs # #[napi] exports (path mode + content mode)
│ ├── package.json # npm package config
│ └── build.rs # napi-build
├── docs/
│ └── js-api.md # Full JS API reference
└── MIGRATION.md # Migration guide for dependents
MIT