{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "dependency-cruiser rule set",
    "description": "A set of properties describing what dependencies are forbidden and what dependencies are allowed.",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        "forbidden": {
            "type": "array",
            "description": "A list of rules that describe dependencies that are not allowed. dependency-cruiser will emit a separate error (warning/ informational) messages for each violated rule.",
            "items": {
                "$ref": "#/definitions/ForiddenRuleType"
            }
        },
        "allowed": {
            "type": "array",
            "description": "A list of rules that describe dependencies that are allowed. dependency-cruiser will emit the warning message 'not-in-allowed' for each dependency that does not at least meet one of them.",
            "items": {
                "$ref" :"#/definitions/RuleType"
            }
        },
        "allowedSeverity": {
            "$ref": "#/definitions/SeverityType",
            "description": "Severity to use when a dependency is not in the 'allowed' set of rules. Defaults to 'warn'"
        },
        "options": {
            "type": "object",
            "description": "Runtime configuration options",
            "additionalProperties": false,
            "properties": {
                "doNotFollow": {
                    "type": "string",
                    "description": "a regular expression for modules to include, but not follow further"
                },
                "exclude": {
                    "type": "string",
                    "description": "a regular expression for excluding modules"
                },
                "moduleSystems": {
                    "type": "array",
                    "description": "list of module systems to cruise. Defaults to [amd, cjs, es6]",
                    "items": {
                        "type": "string",
                        "enum": [
                            "amd",
                            "cjs",
                            "es6",
                            "tsd"
                        ]
                    }
                },
                "prefix": {
                    "type": "string"
                },
                "tsPreCompilationDeps": {
                    "type": "boolean",
                    "description": "if true detect dependencies that only exist before typescript-to-javascript compilation."
                },
                "preserveSymlinks": {
                    "type": "boolean",
                    "description": "if true leave symlinks untouched, otherwise use the realpath. Defaults to `false` (which is also nodejs's default behavior since version 6)"
                },
                "webpackConfig": {
                    "type": "object",
                    "additionalProperties": false,
                    "description": "Webpack configuration to use to get resolve options from",
                    "properties": {
                        "fileName": {
                            "type": "string",
                            "description": "The webpack conf file to use (typically something like 'webpack.conf.js')"
                        },
                        "env": {
                            "description": "Environment to pass if your config file returns a function",
                            "oneOf": [{
                                "type": "object"
                            }, {
                                "type": "string"
                            }]
                        },
                        "arguments": {
                            "type": "object",
                            "description": "Arguments to pass if your config file returns a function. E.g. {mode: 'production'} if you want to use webpack 4's 'mode' feature"
                        }
                    }
                }
            }
        }
    },
    "definitions": {
        "RuleType": {
            "type": "object",
            "required": [ "from", "to" ],
            "additionalProperties": false,
            "properties": {
                "comment" : {
                    "type": "string"
                },
                "from": {
                    "$ref": "#/definitions/FromRestrictionType"
                },
                "to": {
                    "$ref": "#/definitions/ToRestrictionType"
                }
            }
        },
        "ForiddenRuleType": {
            "type": "object",
            "required": [ "from", "to" ],
            "additionalProperties": false,
            "properties": {
                "name": {
                    "type": "string",
                    "description": "A short name for the rule - will appear in reporters to enable customers to quickly identify a violated rule. Try to keep them short, eslint style. E.g. 'not-to-core' for a rule forbidding dependencies on core modules, or 'not-to-unresolvable' for one that prevents dependencies on modules that probably don't exist."
                },
                "severity": { "$ref": "#/definitions/SeverityType"},
                "comment": {
                    "type": "string",
                    "description": "You can use this field to document why the rule is there."
                },
                "from": {
                    "$ref": "#/definitions/FromRestrictionType"
                },
                "to": {
                    "$ref": "#/definitions/ToRestrictionType"
                 }
            }
        },
        "FromRestrictionType": {
            "type": "object",
            "description": "Criteria an end of a dependency should match to be caught by this rule. Leave it empty if you want any module to be matched.",
            "additionalProperties": false,
            "properties": {
                "path": {
                    "type": "string",
                    "description": "A regular expression an end of a dependency should match to be catched by this rule."
                },
                "pathNot": {
                    "type": "string",
                    "description": "A regular expression an end of a dependency should NOT match to be catched by this rule."
                },
                "orphan": {
                    "type": "boolean",
                    "description": "Whether or not to match when the module is an orphan (= has no incoming or outgoing dependencies). When this property it is part of a rule, dependency-cruiser will ignore the 'to' part."
                }
            }
        },
        "ToRestrictionType": {
            "type": "object",
            "description": "Criteria the 'to' end of a dependency should match to be caught by this rule. Leave it empty if you want any module to be matched.",
            "additionalProperties": false,
            "properties" : {
                "path": {
                    "type": "string",
                    "description": "A regular expression an end of a dependency should match to be catched by this rule."
                },
                "pathNot": {
                    "type": "string",
                    "description": "A regular expression an end of a dependency should NOT match to be catched by this rule."
                },
                "couldNotResolve": {
                    "type": "boolean",
                    "description": "Whether or not to match modules dependency-cruiser could not resolve (and probably aren't on disk). For this one too: leave out if you don't care either way."
                },
                "circular": {
                    "type": "boolean",
                    "description": "Whether or not to match when following to the to will ultimately end up in the from."
                },
                "dependencyTypes": {
                    "type": "array",
                    "description": "Whether or not to match modules of any of these types (leaving out matches any of them)",
                    "items": { "$ref": "#/definitions/DependencyType" }
                },
                "moreThanOneDependencyType": {
                    "type": "boolean",
                    "description": "If true matches dependencies with more than one dependency type (e.g. defined in _both_ npm and npm-dev)"
                },
                "license": {
                    "type": "string",
                    "description": "Whether or not to match modules that were released under one of the mentioned licenses. E.g. to flag GPL-1.0, GPL-2.0 licensed modules (e.g. because your app is not compatible with the GPL) use \"GPL\""
                },
                "licenseNot": {
                    "type": "string",
                    "description": "Whether or not to match modules that were NOT released under one of the mentioned licenses. E.g. to flag everyting non MIT use \"MIT\" here"
                }

            }
        },
        "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"
            ]
        },
        "DependencyType": {
            "type": "string",
            "enum": [
                "aliased",
                "core",
                "deprecated",
                "local",
                "npm",
                "npm-bundled",
                "npm-dev",
                "npm-no-pkg",
                "npm-optional",
                "npm-peer",
                "npm-unknown",
                "undetermined",
                "unknown"
            ]
        }
    }
}
