{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "yas-http",
  "oneOf": [
    {
      "$ref": "#/definitions/$id__Server"
    },
    {
      "$ref": "#/definitions/$id__Summary"
    },
    {
      "$ref": "#/definitions/$id__Doc_MD"
    },
    {
      "$ref": "#/definitions/$id__Api"
    }
  ],
  "definitions": {
    "$id__Api": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "$id/Api": {
          "anyOf": [
            {
              "$ref": "#/definitions/$id_api"
            },
            {
              "type": "object",
              "properties": {
                "method": {
                  "$ref": "#/definitions/$id__httpMethod",
                  "default": "GET"
                }
              }
            },
            {
              "type": "object",
              "properties": {
                "body": {
                  "$ref": "#/definitions/getVarObjectString",
                  "description": "Request body"
                }
              }
            }
          ],
          "description": "Custom request"
        },
        "$id/Get": {
          "$ref": "#/definitions/$id_api",
          "description": "Get request"
        },
        "$id/Head": {
          "$ref": "#/definitions/$id_api",
          "description": "Head request"
        },
        "$id/Delete": {
          "$ref": "#/definitions/$id_api",
          "description": "Delete request"
        },
        "$id/Patch": {
          "description": "Patch request",
          "anyOf": [
            {
              "$ref": "#/definitions/$id_api"
            },
            {
              "type": "object",
              "properties": {
                "body": {
                  "$ref": "#/definitions/getVarObjectString",
                  "description": "Request body"
                }
              }
            }
          ]
        },
        "$id/Post": {
          "description": "Post request",
          "anyOf": [
            {
              "$ref": "#/definitions/$id_api"
            },
            {
              "type": "object",
              "properties": {
                "body": {
                  "$ref": "#/definitions/getVarObjectString",
                  "description": "Request body"
                }
              }
            }
          ]
        },
        "$id/Put": {
          "description": "Put request",
          "anyOf": [
            {
              "$ref": "#/definitions/$id_api"
            },
            {
              "type": "object",
              "properties": {
                "body": {
                  "$ref": "#/definitions/getVarObjectString",
                  "description": "Request body"
                }
              }
            }
          ]
        }
      }
    },
    "$id_api": {
      "description": "API request",
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "...": "defaultAttrs",
        "title": {
          "$ref": "#/definitions/getVar",
          "description": "Request title"
        },
        "description": {
          "$ref": "#/definitions/getVar",
          "description": "Request description"
        },
        "baseURL": {
          "$ref": "#/definitions/getVar",
          "description": "Host name and prefix path",
          "examples": [
            "http://localhost/user-service"
          ]
        },
        "url": {
          "$ref": "#/definitions/getVar",
          "description": "Full URL (Got no baseURL) or subpath(Got baseURL)",
          "examples": [
            "http://localhost/user-service/users",
            "/users"
          ]
        },
        "config": {
          "$ref": "#/definitions/getVarObjectString",
          "description": "Request config"
        },
        "params": {
          "$ref": "#/definitions/getVarObjectString",
          "description": "Request params. (In the example, url is '/product/1')"
        },
        "query": {
          "$ref": "#/definitions/getVarObjectString",
          "description": "Request querystring (In the example, url is appended '?order=name')"
        },
        "headers": {
          "$ref": "#/definitions/getVarObjectString",
          "description": "Request headers"
        },
        "saveTo": {
          "$ref": "#/definitions/getVar",
          "description": "Request file to server then download and save to this path"
        },
        "timeout": {
          "description": "Request timeout",
          "$ref": "#/definitions/time"
        },
        "doc": {
          "anyOf": [
            {
              "description": "Document it",
              "type": "boolean"
            },
            {
              "type": "object",
              "description": "Document it",
              "properties": {
                "tags": {
                  "description": "Set tags for the API in document",
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          ]
        },
        "var": {
          "description": "Set response data in global vars",
          "$ref": "#/definitions/setVar"
        },
        "validate": {
          "type": "array",
          "items": {
            "...": "validate",
            "description": "Validate API after received response"
          }
        }
      }
    },
    "$id__Doc_MD": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "$id/Doc/MD": {
          "description": "Api Document",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "title": {
              "$ref": "#/definitions/getVar",
              "description": "API document title"
            },
            "description": {
              "$ref": "#/definitions/getVar",
              "description": "API document description"
            },
            "signature": {
              "$ref": "#/definitions/getVar",
              "description": "Developer information",
              "examples": [
                "[Doan Thuan Thanh](mailto:doanthuanthanh88@gmail.com)"
              ]
            },
            "outFile": {
              "$ref": "#/definitions/getVar",
              "description": "Ouptut path of API document file"
            }
          }
        }
      }
    },
    "$id__Summary": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "$id/Summary": {
          "description": "Summary API requests",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "title": {
              "$ref": "#/definitions/getVar",
              "description": "Description"
            }
          }
        }
      }
    },
    "$id__Server": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "$id/Server": {
          "description": "Mock API Server",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "...": "defaultAttrs",
            "title": {
              "$ref": "#/definitions/getVar",
              "description": "Description"
            },
            "timeout": {
              "description": "Server will be stoped after timeout",
              "$ref": "#/definitions/time"
            },
            "https": {
              "oneOf": [
                {
                  "type": "boolean",
                  "description": "Enable https"
                },
                {
                  "type": "object",
                  "description": "Enable https with customize `key` and `cert` of https",
                  "properties": {
                    "key": {
                      "type": "string"
                    },
                    "cert": {
                      "type": "string"
                    }
                  }
                }
              ],
              "examples": [
                "0.0.0.0"
              ]
            },
            "host": {
              "type": "string",
              "examples": [
                "0.0.0.0"
              ]
            },
            "port": {
              "type": "number",
              "examples": [
                3000
              ]
            },
            "routers": {
              "type": "array",
              "items": {
                "anyOf": [
                  {
                    "description": "Serve static file",
                    "type": "object",
                    "properties": {
                      "serveIn": {
                        "description": "All of files in the list folders will be served after request to",
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  {
                    "description": "Upload file",
                    "type": "object",
                    "required": [
                      "path",
                      "uploadTo"
                    ],
                    "properties": {
                      "path": {
                        "type": "string",
                        "description": "Request path"
                      },
                      "method": {
                        "$ref": "#/definitions/$id__httpMethod",
                        "default": "POST"
                      },
                      "uploadTo": {
                        "type": "string",
                        "description": "Path which uploading file will be saved after uploaded"
                      }
                    }
                  },
                  {
                    "description": "Auto CRUD APIs",
                    "type": "object",
                    "required": [
                      "path",
                      "uploadTo"
                    ],
                    "properties": {
                      "path": {
                        "type": "string",
                        "description": "Request path"
                      },
                      "CRUD": {
                        "type": "boolean",
                        "description": "Auto create full RESTful API"
                      },
                      "initData": {
                        "type": [
                          "array",
                          "object"
                        ],
                        "description": "Init data"
                      }
                    }
                  },
                  {
                    "description": "Mock API Data",
                    "type": "object",
                    "required": [
                      "path",
                      "response"
                    ],
                    "properties": {
                      "path": {
                        "type": "string",
                        "description": "Request path"
                      },
                      "method": {
                        "$ref": "#/definitions/$id__httpMethod",
                        "default": "GET"
                      },
                      "response": {
                        "type": "object",
                        "description": "Response data",
                        "required": [
                          "data"
                        ],
                        "properties": {
                          "status": {
                            "type": "number"
                          },
                          "statusMessage": {
                            "type": "string"
                          },
                          "headers": {
                            "type": "object"
                          },
                          "data": {
                            "$ref": "#/definitions/getVarAny"
                          }
                        }
                      }
                    }
                  },
                  {
                    "description": "Manual handle request, response by code",
                    "type": "object",
                    "required": [
                      "path",
                      "handler"
                    ],
                    "properties": {
                      "path": {
                        "type": "string",
                        "description": "Request path"
                      },
                      "method": {
                        "$ref": "#/definitions/$id__httpMethod",
                        "default": "GET"
                      },
                      "handle": {
                        "description": "Write code to handle request, response",
                        "$ref": "#/definitions/functional",
                        "examples": [
                          "!function | \n({}){\n  console.log('')\n}"
                        ]
                      }
                    }
                  }
                ]
              }
            }
          },
          "async": {
            "description": "Run asynchronized",
            "$ref": "#/definitions/getVarBooleanString",
            "examples": [
              "true",
              "false",
              "${isAsync}"
            ]
          },
          "loop": {
            "description": "Conditional to check before loop steps. ($.loopValue, $.loopKey)",
            "$ref": "#/definitions/getVarAny",
            "examples": [
              "${[1,2,3,4]}",
              "${{key1: value1, key2: value2}}",
              "${list}",
              "${isRun}"
            ]
          },
          "logLevel": {
            "description": "How to show log",
            "$ref": "#/definitions/logLevel"
          },
          "delay": {
            "description": "Sleep in specific time before keep playing the next",
            "$temp": "time"
          },
          "if": {
            "description": "Check conditional to decide to run it or NOT",
            "$ref": "#/definitions/getVarBooleanString"
          },
          "->": {
            "description": "Expose for others extends",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "<-": {
            "description": "Extends others which is exposed by '->'",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          }
        }
      }
    },
    "$id__httpMethod": {
      "type": "string",
      "description": "Http method",
      "enum": [
        "GET",
        "POST",
        "PUT",
        "PATCH",
        "DELETE",
        "HEAD"
      ]
    }
  }
}