{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://smithy.io/2.0/_static/smithy-build-schema.json",
    "title": "Smithy Build Configuration",
    "description": "Configuration file for building Smithy models. Supports // line comments and ${NAME} environment variable expansion in string values. See https://smithy.io/2.0/guides/smithy-build-json.html",
    "type": "object",
    "required": ["version"],
    "properties": {
        "version": {
            "type": "string",
            "description": "Required. Defines the version of smithy-build. Set to \"1.0\".",
            "enum": ["1.0"]
        },
        "outputDirectory": {
            "type": "string",
            "description": "The location where projections are written. Each projection will create a subdirectory named after the projection, and the artifacts from the projection, including a model.json file, will be placed in the directory.",
            "minLength": 1
        },
        "sources": {
            "type": "array",
            "description": "Provides a list of relative files or directories that contain the models that are considered the source models of the build. When a directory is encountered, all files in the entire directory tree are added as sources. Sources are relative to the configuration file.",
            "items": {
                "type": "string",
                "minLength": 1
            }
        },
        "imports": {
            "type": "array",
            "description": "Provides a list of model files and directories to load when validating and building the model. Imports are a local dependency: they are not considered part of model package being built, but are required to build the model package. Models added through imports are not present in the output of the built-in sources plugin. When a directory is encountered, all files in the entire directory tree are imported. Imports defined at the top-level are used in every projection. Imports are relative to the configuration file.",
            "items": {
                "type": "string",
                "minLength": 1
            }
        },
        "projections": {
            "type": "object",
            "description": "A map of projection names to projection configurations.",
            "additionalProperties": {
                "$ref": "#/$defs/projection"
            },
            "propertyNames": {
                "pattern": "^[A-Za-z0-9]+[A-Za-z0-9\\-_.]*$"
            }
        },
        "plugins": {
            "type": "object",
            "description": "Defines the plugins to apply to the model when building every projection. Plugins are a mapping of plugin IDs to plugin-specific configuration objects.",
            "additionalProperties": {
                "type": "object"
            },
            "propertyNames": {
                "pattern": "^[A-Za-z0-9]+[A-Za-z0-9\\-_.]*(::[A-Za-z0-9]+[A-Za-z0-9\\-_.]*)?$"
            }
        },
        "ignoreMissingPlugins": {
            "type": "boolean",
            "description": "If a plugin can't be found, Smithy will by default fail the build. This setting can be set to true to allow the build to progress even if a plugin can't be found on the classpath.",
            "default": false
        },
        "maven": {
            "$ref": "#/$defs/maven",
            "description": "Defines Java Maven dependencies needed to build the model. Dependencies are used to bring in model imports, build plugins, validators, transforms, and other extensions."
        }
    },
    "$defs": {
        "projection": {
            "type": "object",
            "description": "A projection of a model is a filtered and modified version of a Smithy model that is intended for specific audiences or customers.",
            "properties": {
                "abstract": {
                    "type": "boolean",
                    "description": "Defines the projection as a placeholder that other projections apply. Smithy will not build artifacts for abstract projections. Abstract projections must not define imports or plugins.",
                    "default": false
                },
                "imports": {
                    "type": "array",
                    "description": "Provides a list of relative imports to include when building this specific projection (in addition to any imports defined at the top-level). When a directory is encountered, all files in the directory tree are imported. Imports are relative to the configuration file.",
                    "items": {
                        "type": "string",
                        "minLength": 1
                    }
                },
                "transforms": {
                    "type": "array",
                    "description": "Defines the transformations to apply to the projection. Transformations are used to remove shapes, remove traits, modify trait contents, and any other kind of transformation necessary for the projection. Transforms are applied in the order defined.",
                    "items": {
                        "$ref": "#/$defs/transform"
                    }
                },
                "plugins": {
                    "type": "object",
                    "description": "Defines the plugins to apply to the model when building this projection. Plugins are a mapping of plugin IDs to plugin-specific configuration objects.",
                    "additionalProperties": {
                        "type": "object"
                    },
                    "propertyNames": {
                        "pattern": "^[A-Za-z0-9]+[A-Za-z0-9\\-_.]*(::[A-Za-z0-9]+[A-Za-z0-9\\-_.]*)?$"
                    }
                }
            },
            "if": {
                "properties": { "abstract": { "const": true } },
                "required": ["abstract"]
            },
            "then": {
                "properties": {
                    "imports": { "maxItems": 0 },
                    "plugins": { "maxProperties": 0 }
                }
            }
        },
        "transform": {
            "type": "object",
            "description": "A transform used to filter and modify the model for the projection.",
            "required": ["name"],
            "properties": {
                "name": {
                    "type": "string",
                    "description": "The required name of the transform.",
                    "pattern": "^[A-Za-z0-9]+[A-Za-z0-9\\-_.]*$"
                },
                "args": {
                    "oneOf": [
                        { "type": "object" },
                        {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    ],
                    "description": "Configuration key-value pairs, or an array of strings for backward compatibility. Arrays are automatically converted to {\"__args\": <array>} at load time."
                }
            }
        },
        "maven": {
            "type": "object",
            "description": "Maven dependencies and repositories can be defined in smithy-build.json files, and the Smithy CLI will automatically resolve these dependencies.",
            "properties": {
                "dependencies": {
                    "type": "array",
                    "description": "A list of Maven dependency coordinates in the form of groupId:artifactId:version.",
                    "items": {
                        "type": "string"
                    },
                    "uniqueItems": true
                },
                "repositories": {
                    "type": "array",
                    "description": "A list of Maven repositories to search for dependencies. If no repositories are defined and the SMITHY_MAVEN_REPOS environment variable is not defined, then this value defaults to Maven Central.",
                    "items": {
                        "$ref": "#/$defs/mavenRepository"
                    },
                    "uniqueItems": true
                }
            },
            "additionalProperties": false
        },
        "mavenRepository": {
            "type": "object",
            "description": "A Maven repository configuration.",
            "required": ["url"],
            "properties": {
                "id": {
                    "type": "string",
                    "description": "An optional identifier for the repository.",
                    "minLength": 1
                },
                "url": {
                    "type": "string",
                    "description": "The URL of the repository (for example, https://repo.maven.apache.org/maven2).",
                    "minLength": 1
                },
                "httpCredentials": {
                    "type": "string",
                    "description": "HTTP basic or digest credentials to use with the repository. Credentials are provided in the form of \"username:password\". Credentials SHOULD NOT be defined statically in a smithy-build.json file. Instead, use environment variables to keep credentials out of source control."
                },
                "proxyHost": {
                    "type": "string",
                    "description": "The URL of the proxy to configure for this repository (for example, http://proxy.maven.apache.org:8080).",
                    "minLength": 1
                },
                "proxyCredentials": {
                    "type": "string",
                    "description": "HTTP credentials to use with the proxy for the repository. Credentials are provided in the form of \"username:password\". Credentials SHOULD NOT be defined statically in a smithy-build.json file. Instead, use environment variables to keep credentials out of source control."
                }
            },
            "additionalProperties": false
        }
    }
}
