mirror of
				https://github.com/zulip/zulip.git
				synced 2025-10-31 03:53:50 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			79 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/env node
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| const fs = require("fs");
 | |
| 
 | |
| const jsyaml = require("js-yaml");
 | |
| const ExampleValidator = require("openapi-examples-validator");
 | |
| const SwaggerParser = require("swagger-parser");
 | |
| 
 | |
| function checkRefSiblings(file, path, data) {
 | |
|     let ok = true;
 | |
|     if (typeof data === "object" && data !== null) {
 | |
|         if (
 | |
|             "allOf" in data &&
 | |
|             Object.values(data.allOf).filter((subschema) => !("$ref" in subschema)).length !== 1
 | |
|         ) {
 | |
|             console.error(
 | |
|                 `${file}: Too many inline allOf subschemas at ${JSON.stringify(
 | |
|                     path,
 | |
|                 )}: ${JSON.stringify(data, undefined, 2)}`,
 | |
|             );
 | |
|             ok = false;
 | |
|         }
 | |
|         if ("$ref" in data && Object.entries(data).length !== 1) {
 | |
|             console.error(
 | |
|                 `${file}: Siblings of $ref have no effect at ${JSON.stringify(
 | |
|                     path,
 | |
|                 )}: ${JSON.stringify(data, undefined, 2)}`,
 | |
|             );
 | |
|             ok = false;
 | |
|         }
 | |
|         for (const [key, child] of Array.isArray(data) ? data.entries() : Object.entries(data)) {
 | |
|             if (!checkRefSiblings(file, [...path, key], child)) {
 | |
|                 ok = false;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return ok;
 | |
| }
 | |
| 
 | |
| (async () => {
 | |
|     // Iterate through the changed files, passed in the arguments.
 | |
|     // The two first arguments are the call to the Node interpreter and this
 | |
|     // script, hence the starting point at 2.
 | |
|     for (const file of process.argv.slice(2)) {
 | |
|         try {
 | |
|             const data = jsyaml.load(await fs.promises.readFile(file, "utf8"), {
 | |
|                 filename: file,
 | |
|             });
 | |
|             if (data.openapi !== undefined) {
 | |
|                 if (!checkRefSiblings(file, [], data)) {
 | |
|                     process.exitCode = 1;
 | |
|                 }
 | |
|                 await SwaggerParser.validate(file);
 | |
|                 const res = await ExampleValidator.validateFile(file);
 | |
|                 if (!res.valid) {
 | |
|                     for (const error of res.errors) {
 | |
|                         console.error(error);
 | |
|                     }
 | |
|                     process.exitCode = 1;
 | |
|                 }
 | |
|             }
 | |
|         } catch (error) {
 | |
|             if (error instanceof jsyaml.YAMLException) {
 | |
|                 console.error(error.message);
 | |
|             } else if (error instanceof SyntaxError) {
 | |
|                 console.error(`${file}: ${error.message}`);
 | |
|             } else {
 | |
|                 throw error;
 | |
|             }
 | |
|             process.exitCode = 1;
 | |
|         }
 | |
|     }
 | |
| })().catch((error) => {
 | |
|     console.error(error);
 | |
|     process.exit(1);
 | |
| });
 |