{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "dependency-cruiser output format",
    "type": "object",
    "required": [ "summary", "modules" ],
    "additionalProperties": false,
    "properties": {
        "summary": {
            "type": "object",
            "required": ["violations", "error", "warn", "info", "totalCruised", "optionsUsed"],
            "additionalProperties": false,
            "description": "Data summarizing the found dependencies",
            "properties": {
                "violations": {
                    "type": "array",
                    "description": "A list of violations found in the dependencies. The dependencies themselves also contain this information, this summary is here for convenience.",
                    "items": { "$ref": "#/definitions/ViolationType"}
                },
                "error": {
                    "type": "number",
                    "description": "the number of errors in the dependencies"
                },
                "warn": {
                    "type": "number",
                    "description": "the number of warnings in the dependencies"
                },
                "info": {
                    "type": "number",
                    "description": "the number of informational level notices in the dependencies"
                },
                "totalCruised": {
                    "type": "number",
                    "description": "the number of modules cruised"
                },
                "optionsUsed": { "$ref": "#/definitions/OptionsType" }
            }
        },
        "modules": {
            "type": "array",
            "description": "A list of modules, with for each module the modules it depends upon",
            "items": {
                "type": "object",
                "required": [ "source", "dependencies", "valid" ],
                "additionalProperties": false,
                "properties": {
                    "source": {
                        "type": "string",
                        "description": "The (resolved) file name of the module, e.g. 'src/main/index.js'"
                    },
                    "followable": {
                        "type": "boolean",
                        "description": "Whether or not this is a dependency that can be followed any further. This will be 'false' for for core modules, json, modules that could not be resolved to a file and modules that weren't followed because it matches the doNotFollow expression."
                    },
                    "matchesDoNotFollow": {
                        "type": "boolean",
                        "description": "'true' if the file name of this module matches the doNotFollow regular expression"
                    },
                    "coreModule": {
                        "type": "boolean",
                        "description": "Whether or not this is a node.js core module"
                    },
                    "couldNotResolve": {
                        "type": "boolean",
                        "description": "'true' if dependency-cruiser could not resolve the module name in the source code to a file name or core module. 'false' in all other cases."
                    },
                    "dependencyTypes": {
                        "type": "array",
                        "items": { "$ref": "#/definitions/DependencyType" },
                        "description": "the type of inclusion - local, core, unknown (= we honestly don't know), undetermined (= we didn't bother determining it) or one of the npm dependencies defined in a package.jsom ('npm' for 'depenencies', 'npm-dev', 'npm-optional', 'npm-peer', 'npm-no-pkg' for development, optional, peer dependencies and dependencies in node_modules but not in package.json respectively)"
                    },
                    "license": {
                        "type": "string",
                        "description": "the license, if known (usually known for modules pulled from npm, not for local ones)"
                    },
                    "orphan": {
                        "type": "boolean",
                        "description": "'true' if this dependency does not have dependencies, and no module has it as a dependency"
                    },
                    "valid": {
                        "type": "boolean",
                        "description": "'true' if this module violated a rule; 'false' in all other cases. The violated rule will be in the 'rule' object at the same level."
                    },
                    "rules": {
                        "type": "array",
                        "items": {"$ref": "#/definitions/RuleSummaryType"},
                        "description": "an array of rules violated by this module - left out if the module is valid"
                    },
                    "dependencies": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "required": [
                                "module",
                                "resolved",
                                "coreModule",
                                "dependencyTypes",
                                "followable",
                                "couldNotResolve",
                                "moduleSystem",
                                "valid"
                            ],
                            "additionalProperties": false,
                            "properties": {
                                "module": {
                                    "type": "string",
                                    "description": "The name of the module as it appeared in the source code, e.g. './main'"
                                },
                                "resolved": {
                                    "type": "string",
                                    "description": "The (resolved) file name of the module, e.g. 'src/main//index.js'"
                                },
                                "coreModule": {
                                    "type": "boolean",
                                    "description": "Whether or not this is a node.js core module - deprecated in favor of dependencyType === core"
                                },
                                "dependencyTypes": {
                                    "type": "array",
                                    "items": { "$ref": "#/definitions/DependencyType" },
                                    "description": "the type of inclusion - local, core, unknown (= we honestly don't know), undetermined (= we didn't bother determining it) or one of the npm dependencies defined in a package.jsom ('npm' for 'depenencies', 'npm-dev', 'npm-optional', 'npm-peer', 'npm-no-pkg' for development, optional, peer dependencies and dependencies in node_modules but not in package.json respectively)"
                                },
                                "license": {
                                    "type": "string",
                                    "description": "the license, if known (usually known for modules pulled from npm, not for local ones)"
                                },
                                "followable": {
                                    "type": "boolean",
                                    "description": "Whether or not this is a dependency that can be followed any further. This will be 'false' for for core modules, json, modules that could not be resolved to a file and modules that weren't followed because it matches the doNotFollow expression."
                                },
                                "matchesDoNotFollow": {
                                    "type": "boolean",
                                    "description": "'true' if the file name of this module matches the doNotFollow regular expression"
                                },
                                "couldNotResolve": {
                                    "type": "boolean",
                                    "description": "'true' if dependency-cruiser could not resulve the module name in the source code to a file name or core module. 'false' in all other cases."
                                },
                                "circular": {
                                    "type": "boolean",
                                    "description": "'true' if following this dependency will ultimately return to the source, false in all other cases"
                                },
                                "moduleSystem": { "$ref": "#/definitions/ModuleSystemType" },
                                "valid": {
                                    "type": "boolean",
                                    "description": "'true' if this dependency violated a rule; 'false' in all other cases. The violated rule will be in the 'rule' object at the same level."
                                },
                                "rules": {
                                    "type": "array",
                                    "items": {"$ref": "#/definitions/RuleSummaryType"},
                                    "description": "an array of rules violated by this dependency - left out if the dependency is valid"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "SeverityType": {
            "type": "string",
            "description": "How severe a violation of a rule is. The 'error' severity will make some reporters return a non-zero exit code, so if you want e.g. a build to stop when there's a rule violated: use that.",
            "enum": [
                "error",
                "warn",
                "info"
            ]
        },
        "RuleSummaryType": {
            "type": "object",
            "description": "If there was a rule violation (valid === false), this object contains the name of the rule and severity of violating it.",
            "required": [ "name", "severity" ],
            "additionalProperties": false,
            "properties": {
                "name": {
                    "type": "string",
                    "description": "The (short, eslint style) name of the violated rule. Typically something like 'no-core-punycode' or 'no-outside-deps'."
                },
                "severity": { "$ref": "#/definitions/SeverityType"}
            }
        },
        "ViolationType": {
            "type": "object",
            "required": ["from", "to", "rule"],
            "additionalProperties": false,
            "properties" : {
                "from": {
                    "type": "string"
                },
                "to": {
                    "type": "string"
                },
                "rule": { "$ref": "#/definitions/RuleSummaryType"}
            }
        },
        "ModuleSystemType": {
            "type": "string",
            "enum": [
                "cjs",
                "amd",
                "es6",
                "tsd"
            ]
        },
        "OutputType": {
            "type": "string",
            "enum": [
                "html",
                "dot",
                "err",
                "json"
            ]
        },
        "DependencyType": {
            "type": "string",
            "enum": [
                "aliased",
                "core",
                "deprecated",
                "local",
                "npm",
                "npm-bundled",
                "npm-dev",
                "npm-no-pkg",
                "npm-optional",
                "npm-peer",
                "npm-unknown",
                "undetermined",
                "unknown"
            ]
        },
        "OptionsType": {
            "type": "object",
            "description": "the (command line) options used to generate the dependency-tree",
            "additionalProperties": false,
            "properties": {
                "rulesFile": {
                    "type": "string",
                    "description": "The rules file used to validate the dependencies (if any)"
                },
                "outputTo": {
                    "type": "string",
                    "description": "File the output was written to ('-' for stdout)"
                },
                "doNotFollow": {
                    "type": "string",
                    "description": "The regular expression used for preventing modules from being cruised any further"
                },
                "exclude": {
                    "type": "string",
                    "description": "The regular expression used for excluding modules from being cruised"
                },
                "maxDepth": {
                    "type": "number",
                    "description": "The maximum cruise depth specified. 0 means no maximum specified"
                },
                "moduleSystems": {
                    "type": "array",
                    "items": {"$ref": "#/definitions/ModuleSystemType" }
                },
                "outputType": { "$ref": "#/definitions/OutputType" },
                "prefix": {
                    "type": "string"
                },
                "tsPreCompilationDeps": {
                    "type": "boolean"
                },
                "preserveSymlinks": {
                    "type": "boolean"
                },
                "webpackConfig": {
                    "type": "object",
                    "additionalProperties": false,
                    "description": "The webpack configuration options used for the cruise",
                    "properties": {
                        "fileName": {
                            "type": "string",
                            "description": "The name of the webpack configuration file used"
                        },
                        "env": {
                            "description": "The 'env' parameters passed",
                            "oneOf": [{
                                "type": "object"
                            }, {
                                "type": "string"
                            }]
                        },
                        "arguments": {
                            "type": "object",
                            "description": "The arguments used"
                        }
                    }
                }
            }
        }
    }
}
