{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "$schema": {
      "type": "string",
      "format": "uri",
      "description": "Editor schema hint. Xeer does not fetch this URL during validation."
    },
    "format": {
      "type": "string",
      "const": "xeer.application-source.v0",
      "description": "Manifest protocol discriminator; exactly xeer.application-source.v0."
    },
    "name": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9-]{1,62}$",
      "description": "Lowercase application slug, between 2 and 63 characters."
    },
    "entrypoints": {
      "type": "object",
      "properties": {
        "client": {
          "type": "string",
          "minLength": 1
        },
        "server": {
          "type": "string",
          "minLength": 1
        }
      },
      "required": [
        "client",
        "server"
      ],
      "additionalProperties": false,
      "description": "Project-relative client and server source entrypoints."
    },
    "app": {
      "type": "object",
      "properties": {
        "spa": {
          "type": "boolean"
        },
        "title": {
          "type": "string",
          "minLength": 1,
          "maxLength": 120
        },
        "language": {
          "type": "string",
          "maxLength": 35,
          "pattern": "^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$"
        },
        "description": {
          "type": "string",
          "maxLength": 300
        },
        "favicon": {
          "type": "string",
          "minLength": 2,
          "maxLength": 256,
          "pattern": "^\\/[A-Za-z0-9._~!$&'()*+,;=:@/-]+$"
        }
      },
      "additionalProperties": false,
      "description": "Browser metadata and SPA behavior."
    },
    "database": {
      "type": "object",
      "properties": {
        "version": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 9007199254740991
        },
        "tables": {
          "type": "object",
          "propertyNames": {
            "type": "string",
            "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
          },
          "additionalProperties": {
            "type": "object",
            "properties": {
              "fields": {
                "type": "object",
                "propertyNames": {
                  "type": "string",
                  "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
                },
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string",
                      "enum": [
                        "string",
                        "number",
                        "boolean",
                        "datetime",
                        "bytes",
                        "json",
                        "ref"
                      ]
                    },
                    "optional": {
                      "type": "boolean"
                    },
                    "maxLength": {
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 9007199254740991
                    },
                    "unique": {
                      "type": "boolean"
                    },
                    "enum": {
                      "minItems": 1,
                      "maxItems": 1000,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "maxLength": 1000
                      }
                    },
                    "default": {
                      "anyOf": [
                        {
                          "type": "string",
                          "maxLength": 1000
                        },
                        {
                          "type": "number"
                        },
                        {
                          "type": "boolean"
                        }
                      ]
                    },
                    "collate": {
                      "type": "string",
                      "enum": [
                        "binary",
                        "nocase",
                        "rtrim"
                      ]
                    },
                    "table": {
                      "type": "string",
                      "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
                    },
                    "onDelete": {
                      "type": "string",
                      "enum": [
                        "noAction",
                        "restrict",
                        "cascade",
                        "setNull",
                        "setDefault"
                      ]
                    },
                    "onUpdate": {
                      "type": "string",
                      "enum": [
                        "noAction",
                        "restrict",
                        "cascade",
                        "setNull",
                        "setDefault"
                      ]
                    },
                    "generated": {
                      "type": "object",
                      "properties": {
                        "expression": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 1000
                        },
                        "stored": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "expression"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "type"
                  ],
                  "additionalProperties": false
                }
              },
              "indexes": {
                "type": "object",
                "propertyNames": {
                  "type": "string",
                  "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
                },
                "additionalProperties": {
                  "anyOf": [
                    {
                      "minItems": 1,
                      "type": "array",
                      "items": {
                        "type": "string",
                        "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "columns": {
                          "minItems": 1,
                          "type": "array",
                          "items": {
                            "anyOf": [
                              {
                                "type": "string",
                                "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "column": {
                                    "type": "string",
                                    "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
                                  },
                                  "collate": {
                                    "type": "string",
                                    "enum": [
                                      "binary",
                                      "nocase",
                                      "rtrim"
                                    ]
                                  },
                                  "desc": {
                                    "type": "boolean"
                                  }
                                },
                                "required": [
                                  "column"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "expression": {
                                    "type": "string",
                                    "minLength": 1,
                                    "maxLength": 1000
                                  },
                                  "desc": {
                                    "type": "boolean"
                                  }
                                },
                                "required": [
                                  "expression"
                                ],
                                "additionalProperties": false
                              }
                            ]
                          }
                        },
                        "unique": {
                          "type": "boolean"
                        },
                        "where": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 1000
                        }
                      },
                      "required": [
                        "columns"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              },
              "unique": {
                "type": "array",
                "items": {
                  "minItems": 1,
                  "type": "array",
                  "items": {
                    "type": "string",
                    "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
                  }
                }
              },
              "checks": {
                "type": "object",
                "propertyNames": {
                  "type": "string",
                  "pattern": "^[A-Za-z][A-Za-z0-9_]*$"
                },
                "additionalProperties": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 1000
                }
              },
              "idSource": {
                "type": "string",
                "enum": [
                  "runtime",
                  "application"
                ]
              }
            },
            "required": [
              "fields"
            ],
            "additionalProperties": false
          }
        }
      },
      "required": [
        "tables"
      ],
      "additionalProperties": false,
      "description": "Typed application database schema. Requires the database capability."
    },
    "storage": {
      "type": "object",
      "properties": {
        "maxObjectBytes": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 26214400
        },
        "readBytes": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 134217728
        },
        "writeBytes": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 134217728
        }
      },
      "additionalProperties": false,
      "description": "Private object-storage limits. Requires the storage capability."
    },
    "capabilities": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "database",
          "storage"
        ]
      },
      "description": "Powers granted to the application. Duplicate names are invalid.",
      "uniqueItems": true
    },
    "client": {
      "type": "object",
      "properties": {
        "runtime": {
          "type": "object",
          "properties": {
            "provider": {
              "type": "string",
              "const": "preact"
            },
            "source": {
              "type": "string",
              "const": "platform"
            }
          },
          "required": [
            "provider"
          ],
          "additionalProperties": false
        }
      },
      "additionalProperties": false,
      "description": "Client runtime selection. Optional; omission means the platform-managed Preact runtime."
    },
    "budgets": {
      "type": "object",
      "properties": {
        "queryRows": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 10000
        },
        "mutationWrites": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 1000
        },
        "requestBytes": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 4194304
        },
        "responseBytes": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 4194304
        },
        "clientBundleBytes": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 10485760
        },
        "liveConnections": {
          "type": "integer",
          "minimum": 0,
          "maximum": 1000
        },
        "streamedBytes": {
          "type": "integer",
          "exclusiveMinimum": 0,
          "maximum": 67108864
        }
      },
      "additionalProperties": false,
      "description": "Per-operation resource ceilings, each lowerable from platform defaults."
    }
  },
  "required": [
    "format",
    "name",
    "entrypoints"
  ],
  "additionalProperties": false,
  "$id": "https://docs.xeer.run/application-v0.schema.json",
  "title": "Xeer application source manifest v0",
  "description": "The complete declarative application manifest read by the Xeer compiler.",
  "allOf": [
    {
      "if": {
        "required": [
          "database"
        ]
      },
      "then": {
        "required": [
          "capabilities"
        ],
        "properties": {
          "capabilities": {
            "type": "array",
            "contains": {
              "const": "database"
            }
          }
        }
      }
    },
    {
      "if": {
        "required": [
          "capabilities"
        ],
        "properties": {
          "capabilities": {
            "type": "array",
            "contains": {
              "const": "database"
            }
          }
        }
      },
      "then": {
        "required": [
          "database"
        ]
      }
    },
    {
      "if": {
        "required": [
          "storage"
        ]
      },
      "then": {
        "required": [
          "capabilities"
        ],
        "properties": {
          "capabilities": {
            "type": "array",
            "contains": {
              "const": "storage"
            }
          }
        }
      }
    },
    {
      "if": {
        "required": [
          "capabilities"
        ],
        "properties": {
          "capabilities": {
            "type": "array",
            "contains": {
              "const": "storage"
            }
          }
        }
      },
      "then": {
        "required": [
          "storage"
        ]
      }
    }
  ]
}
