graphql-mandatory-validator
Version:
A GraphQL schema validator for mandatory fields with default values and composite type validation
142 lines (115 loc) • 3.91 kB
JavaScript
const { GraphQLValidator } = require('../dist/index.js');
const path = require('path');
function showHelp() {
console.log(`
GraphQL Validator CLI
Usage:
graphql-validator [options]
Options:
--mode <staged|all> Validation mode (default: staged)
staged: Only validate staged files in git
all: Validate all GraphQL files in project
--base-dir <path> Base directory to search for GraphQL files
(default: src/type-defs)
--project-root <path> Project root directory (default: current directory)
--no-color Disable colored output
--no-exit Don't exit process on validation failure
--help, -h Show this help message
Examples:
graphql-validator # Validate staged files (pre-commit)
graphql-validator --mode all # Validate all files in project
graphql-validator --base-dir schema # Use custom GraphQL directory
graphql-validator --mode staged --no-exit # For lint-staged integration
graphql-validator --mode all --no-color # CI/CD friendly output
Validation Rules:
• Mandatory scalar fields must have @defaultValue directives
• Mandatory composite types must contain ≥1 mandatory field
• Staged mode only validates newly added lines (git diff)
• Full mode validates entire project
`);
}
function parseArgs() {
const args = process.argv.slice(2);
const options = {
mode: 'staged',
baseDir: 'src/type-defs',
projectRoot: process.cwd(),
colorOutput: true,
exitOnError: true,
};
for (let i = 0; i < args.length; i++) {
const arg = args[i];
switch (arg) {
case '--help':
case '-h':
showHelp();
process.exit(0);
break;
case '--mode':
if (i + 1 < args.length) {
const mode = args[++i];
if (mode === 'staged' || mode === 'all') {
options.mode = mode;
} else {
console.error(`Invalid mode: ${mode}. Use 'staged' or 'all'`);
process.exit(1);
}
} else {
console.error('--mode requires a value');
process.exit(1);
}
break;
case '--base-dir':
if (i + 1 < args.length) {
options.baseDir = args[++i];
} else {
console.error('--base-dir requires a value');
process.exit(1);
}
break;
case '--project-root':
if (i + 1 < args.length) {
options.projectRoot = path.resolve(args[++i]);
} else {
console.error('--project-root requires a value');
process.exit(1);
}
break;
case '--no-color':
options.colorOutput = false;
break;
case '--no-exit':
options.exitOnError = false;
break;
default:
// Check if argument looks like a file path (lint-staged passes these)
if (arg.endsWith('.graphql') || arg.includes('/')) {
// Ignore file paths - our validator finds staged files automatically
break;
}
console.error(`Unknown option: ${arg}`);
console.error('Use --help for usage information');
process.exit(1);
}
}
return options;
}
async function main() {
try {
const options = parseArgs();
const validator = new GraphQLValidator({
baseDir: options.baseDir,
colorOutput: options.colorOutput,
exitOnError: options.exitOnError,
});
const result = await validator.run(options.mode, options.projectRoot);
if (!result.success && !options.exitOnError) {
process.exit(1);
}
} catch (error) {
console.error('Error running GraphQL validator:', error.message);
process.exit(1);
}
}
main();