diff --git a/Makefile b/Makefile index fe6cef7..83b4e26 100755 --- a/Makefile +++ b/Makefile @@ -72,11 +72,26 @@ build-docker: docker build -t godoxy-nightly \ --build-arg VERSION="${VERSION}-nightly-${BUILD_DATE}" . +gen-schema-single: + typescript-json-schema --noExtraProps --required --skipLibCheck --tsNodeRegister=true -o schemas/${OUT} schemas/${IN} ${CLASS} + gen-schema: - typescript-json-schema --required --constAsEnum --tsNodeRegister=true -o schemas/config.schema.json schemas/config/config.ts Config - typescript-json-schema --required --constAsEnum --tsNodeRegister=true -o schemas/routes.schema.json schemas/providers/routes.ts Routes - typescript-json-schema --required --constAsEnum --tsNodeRegister=true -o schemas/middleware_compose.schema.json schemas/middlewares/middleware_compose.ts MiddlewareComposeConfig - # typescript-json-schema --required --constAsEnum --tsNodeRegister=true -o schemas/docker_routes.schema.json schemas/docker.ts DockerRoutes + make IN=config/config.ts \ + CLASS=Config \ + OUT=config.schema.json \ + gen-schema-single + make IN=providers/routes.ts \ + CLASS=Routes \ + OUT=routes.schema.json \ + gen-schema-single + make IN=middlewares/middleware_compose.ts \ + CLASS=MiddlewareCompose \ + OUT=middleware_compose.schema.json \ + gen-schema-single + make IN=docker.ts \ + CLASS=DockerRoutes \ + OUT=docker_routes.schema.json \ + gen-schema-single push-github: git push origin $(shell git rev-parse --abbrev-ref HEAD) \ No newline at end of file diff --git a/schemas/config.schema.json b/schemas/config.schema.json index 12f6a35..d944ced 100644 --- a/schemas/config.schema.json +++ b/schemas/config.schema.json @@ -20,6 +20,9 @@ }, "AutocertConfig": { "anyOf": [ + { + "$ref": "#/definitions/LocalOptions" + }, { "$ref": "#/definitions/CloudflareOptions" }, @@ -85,6 +88,7 @@ "type": "string" }, "options": { + "additionalProperties": false, "properties": { "client_id": { "type": "string" @@ -105,9 +109,7 @@ "type": "object" }, "provider": { - "enum": [ - "clouddns" - ], + "const": "clouddns", "type": "string" } }, @@ -139,6 +141,7 @@ "type": "string" }, "options": { + "additionalProperties": false, "properties": { "auth_token": { "type": "string" @@ -150,9 +153,7 @@ "type": "object" }, "provider": { - "enum": [ - "cloudflare" - ], + "const": "cloudflare", "type": "string" } }, @@ -184,6 +185,7 @@ "type": "string" }, "options": { + "additionalProperties": false, "properties": { "token": { "type": "string" @@ -195,9 +197,7 @@ "type": "object" }, "provider": { - "enum": [ - "duckdns" - ], + "const": "duckdns", "type": "string" } }, @@ -213,20 +213,16 @@ "additionalProperties": false, "properties": { "name": { - "description": "Name of the notification provider", "type": "string" }, "provider": { - "enum": [ - "gotify" - ], + "const": "gotify", "type": "string" }, "token": { "type": "string" }, "url": { - "description": "URL of the notification provider", "format": "uri", "type": "string" } @@ -239,6 +235,352 @@ ], "type": "object" }, + "LocalOptions": { + "additionalProperties": false, + "properties": { + "cert_path": { + "type": "string" + }, + "domains": { + "items": { + "pattern": "^(\\*\\.)?(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$" + }, + "type": "array" + }, + "email": { + "format": "email", + "type": "string" + }, + "key_path": { + "type": "string" + }, + "provider": { + "const": "local", + "type": "string" + } + }, + "required": [ + "domains", + "email", + "provider" + ], + "type": "object" + }, + "MiddlewareComposeMap": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "use": { + "enum": [ + "CustomErrorPage", + "ErrorPage", + "customErrorPage", + "custom_error_page", + "errorPage", + "error_page" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "use": { + "enum": [ + "RedirectHTTP", + "redirectHTTP", + "redirect_http" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "use": { + "enum": [ + "SetXForwarded", + "setXForwarded", + "set_x_forwarded" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "use": { + "enum": [ + "HideXForwarded", + "hideXForwarded", + "hide_x_forwarded" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allow": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + }, + "message": { + "default": "IP not allowed", + "description": "Error message when blocked", + "type": "string" + }, + "status": { + "$ref": "#/definitions/StatusCode", + "default": 403, + "description": "HTTP status code when blocked (alias of status_code)" + }, + "status_code": { + "$ref": "#/definitions/StatusCode", + "default": 403, + "description": "HTTP status code when blocked" + }, + "use": { + "enum": [ + "CIDRWhitelist", + "cidrWhitelist", + "cidr_whitelist" + ], + "type": "string" + } + }, + "required": [ + "allow", + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "recursive": { + "default": false, + "description": "Recursively resolve the IP", + "type": "boolean" + }, + "use": { + "enum": [ + "cloudflareRealIp", + "cloudflare_real_ip" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "add_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Add HTTP headers", + "type": "object" + }, + "hide_headers": { + "description": "Hide HTTP headers", + "items": { + "type": "string" + }, + "type": "array" + }, + "set_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Set HTTP headers", + "type": "object" + }, + "use": { + "enum": [ + "ModifyRequest", + "Request", + "modifyRequest", + "modify_request", + "request" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "add_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Add HTTP headers", + "type": "object" + }, + "hide_headers": { + "description": "Hide HTTP headers", + "items": { + "type": "string" + }, + "type": "array" + }, + "set_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Set HTTP headers", + "type": "object" + }, + "use": { + "enum": [ + "ModifyResponse", + "Response", + "modifyResponse", + "modify_response", + "response" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allowed_groups": { + "description": "Allowed groups", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "allowed_users": { + "description": "Allowed users", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "use": { + "enum": [ + "OIDC", + "oidc" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "average": { + "description": "Average number of requests allowed in a period", + "type": "number" + }, + "burst": { + "description": "Maximum number of requests allowed in a period", + "type": "number" + }, + "period": { + "default": "1s", + "description": "Duration of the rate limit", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "use": { + "enum": [ + "RateLimit", + "rateLimit", + "rate_limit" + ], + "type": "string" + } + }, + "required": [ + "average", + "burst", + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "from": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + }, + "header": { + "default": "X-Real-IP", + "description": "Header to get the client IP from", + "pattern": "^[a-zA-Z0-9\\-]+$", + "type": "string" + }, + "recursive": { + "default": false, + "description": "Recursive resolve the IP", + "type": "boolean" + }, + "use": { + "enum": [ + "RealIP", + "realIP", + "real_ip" + ], + "type": "string" + } + }, + "required": [ + "from", + "use" + ], + "type": "object" + } + ] + }, "OVHEndpoint": { "enum": [ "kimsufi-ca", @@ -271,6 +613,7 @@ "type": "string" }, "options": { + "additionalProperties": false, "properties": { "api_endpoint": { "$ref": "#/definitions/OVHEndpoint" @@ -293,9 +636,7 @@ "type": "object" }, "provider": { - "enum": [ - "ovh" - ], + "const": "ovh", "type": "string" } }, @@ -327,6 +668,7 @@ "type": "string" }, "options": { + "additionalProperties": false, "properties": { "api_endpoint": { "$ref": "#/definitions/OVHEndpoint" @@ -338,6 +680,7 @@ "type": "string" }, "oauth2_config": { + "additionalProperties": false, "properties": { "client_id": { "type": "string" @@ -361,9 +704,7 @@ "type": "object" }, "provider": { - "enum": [ - "ovh" - ], + "const": "ovh", "type": "string" } }, @@ -375,127 +716,6 @@ ], "type": "object" }, - "Partial": { - "properties": { - "allow": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "message": { - "default": "IP not allowed", - "description": "Error message when blocked", - "type": "string" - }, - "status_code": { - "$ref": "#/definitions/StatusCode", - "default": 403, - "description": "HTTP status code when blocked" - } - }, - "type": "object" - }, - "Partial": { - "properties": { - "recursive": { - "default": false, - "description": "Recursively resolve the IP", - "type": "boolean" - } - }, - "type": "object" - }, - "Partial": { - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "Partial": { - "type": "object" - }, - "Partial": { - "properties": { - "allowed_groups": { - "description": "Allowed groups", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - }, - "allowed_users": { - "description": "Allowed users", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - } - }, - "type": "object" - }, - "Partial": { - "properties": { - "average": { - "description": "Average number of requests allowed in a period", - "type": "number" - }, - "burst": { - "description": "Maximum number of requests allowed in a period", - "type": "number" - }, - "period": { - "default": "1s", - "description": "Duration of the rate limit", - "pattern": "^([0-9]+(ms|s|m|h))+$", - "type": "string" - } - }, - "type": "object" - }, - "Partial": { - "properties": { - "from": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "header": { - "description": "Header to get the client IP from", - "pattern": "^[a-zA-Z0-9\\-]+$", - "type": "string" - }, - "recursive": { - "default": false, - "description": "Recursive resolve the IP", - "type": "boolean" - } - }, - "type": "object" - }, "StatusCode": { "anyOf": [ { @@ -548,7 +768,6 @@ "description": "Webhook mime type" }, "name": { - "description": "Name of the notification provider", "type": "string" }, "payload": { @@ -556,24 +775,19 @@ "type": "string" }, "provider": { - "enum": [ - "webhook" - ], + "const": "webhook", "type": "string" }, "template": { + "const": "discord", "default": "discord", "description": "Webhook template", - "enum": [ - "discord" - ], "type": "string" }, "token": { "type": "string" }, "url": { - "description": "URL of the notification provider", "format": "uri", "type": "string" } @@ -669,8 +883,10 @@ "type": "integer" }, "fields": { + "additionalProperties": false, "properties": { "cookie": { + "additionalProperties": false, "properties": { "config": { "additionalProperties": { @@ -693,6 +909,7 @@ "type": "object" }, "header": { + "additionalProperties": false, "properties": { "config": { "additionalProperties": { @@ -715,6 +932,7 @@ "type": "object" }, "query": { + "additionalProperties": false, "properties": { "config": { "additionalProperties": { @@ -740,8 +958,10 @@ "type": "object" }, "filters": { + "additionalProperties": false, "properties": { "cidr": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -761,6 +981,7 @@ "type": "object" }, "headers": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -780,6 +1001,7 @@ "type": "object" }, "host": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -799,6 +1021,7 @@ "type": "object" }, "method": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -829,6 +1052,7 @@ "type": "object" }, "status_code": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -866,7 +1090,6 @@ "type": "object" }, "middlewares": { - "additionalProperties": false, "description": "Entrypoint middleware configuration", "examples": [ { @@ -885,414 +1108,7 @@ } ], "items": { - "anyOf": [ - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - } - ] + "$ref": "#/definitions/MiddlewareComposeMap" }, "type": "array" } diff --git a/schemas/config/access_log.ts b/schemas/config/access_log.ts index 63e3071..1438afb 100644 --- a/schemas/config/access_log.ts +++ b/schemas/config/access_log.ts @@ -4,9 +4,6 @@ export const ACCESS_LOG_FORMATS = ["combined", "common", "json"] as const; export type AccessLogFormat = (typeof ACCESS_LOG_FORMATS)[number]; -/** - * @additionalProperties false - */ export type AccessLogConfig = { /** * The size of the buffer. diff --git a/schemas/config/autocert.ts b/schemas/config/autocert.ts index aed8bfa..dde342f 100644 --- a/schemas/config/autocert.ts +++ b/schemas/config/autocert.ts @@ -11,6 +11,7 @@ export const AUTOCERT_PROVIDERS = [ export type AutocertProvider = (typeof AUTOCERT_PROVIDERS)[number]; export type AutocertConfig = + | LocalOptions | CloudflareOptions | CloudDNSOptions | DuckDNSOptions @@ -28,32 +29,25 @@ export interface AutocertConfigBase { key_path?: string; } -/** - * @additionalProperties false - */ +export interface LocalOptions extends AutocertConfigBase { + provider: "local"; +} + export interface CloudflareOptions extends AutocertConfigBase { provider: "cloudflare"; options: { auth_token: string }; } -/** - * @additionalProperties false - */ export interface CloudDNSOptions extends AutocertConfigBase { provider: "clouddns"; options: { client_id: string; - /** - * @format email - */ email: Email; password: string; }; } -/** - * @additionalProperties false - */ + export interface DuckDNSOptions extends AutocertConfigBase { provider: "duckdns"; options: { @@ -73,9 +67,6 @@ export const OVH_ENDPOINTS = [ export type OVHEndpoint = (typeof OVH_ENDPOINTS)[number]; -/** - * @additionalProperties false - */ export interface OVHOptionsWithAppKey extends AutocertConfigBase { provider: "ovh"; options: { @@ -86,9 +77,6 @@ export interface OVHOptionsWithAppKey extends AutocertConfigBase { }; } -/** - * @additionalProperties false - */ export interface OVHOptionsWithOAuth2Config extends AutocertConfigBase { provider: "ovh"; options: { diff --git a/schemas/config/config.ts b/schemas/config/config.ts index b4de625..9b53922 100644 --- a/schemas/config/config.ts +++ b/schemas/config/config.ts @@ -4,9 +4,6 @@ import { EntrypointConfig } from "./entrypoint"; import { HomepageConfig } from "./homepage"; import { Providers } from "./providers"; -/** - * @additionalProperties false - */ export type Config = { /** Optional autocert configuration * diff --git a/schemas/config/entrypoint.ts b/schemas/config/entrypoint.ts index f30b796..a5121a8 100644 --- a/schemas/config/entrypoint.ts +++ b/schemas/config/entrypoint.ts @@ -1,15 +1,12 @@ -import { MiddlewareComposeConfig } from "../middlewares/middleware_compose"; +import { MiddlewareCompose } from "../middlewares/middleware_compose"; import { AccessLogConfig } from "./access_log"; -/** - * @additionalProperties false - */ export type EntrypointConfig = { /** Entrypoint middleware configuration * * @examples require(".").middlewaresExamples */ - middlewares: MiddlewareComposeConfig; + middlewares: MiddlewareCompose; /** Entrypoint access log configuration * * @examples require(".").accessLogExamples diff --git a/schemas/config/homepage.ts b/schemas/config/homepage.ts index 40ec2c8..31f783b 100644 --- a/schemas/config/homepage.ts +++ b/schemas/config/homepage.ts @@ -1,6 +1,3 @@ -/** - * @additionalProperties false - */ export type HomepageConfig = { /** * Use default app categories (uses docker image name) diff --git a/schemas/config/notification.ts b/schemas/config/notification.ts index 10bc1cf..aa90ffc 100644 --- a/schemas/config/notification.ts +++ b/schemas/config/notification.ts @@ -5,19 +5,12 @@ export const NOTIFICATION_PROVIDERS = ["webhook", "gotify"] as const; export type NotificationProvider = (typeof NOTIFICATION_PROVIDERS)[number]; export type NotificationConfig = { - /** - * Name of the notification provider - */ + /* Name of the notification provider */ name: string; - /** - * URL of the notification provider - */ + /* URL of the notification provider */ url: URL; }; -/** - * @additionalProperties false - */ export interface GotifyConfig extends NotificationConfig { provider: "gotify"; /* Gotify token */ @@ -38,9 +31,6 @@ export type WebhookMethod = (typeof WEBHOOK_METHODS)[number]; export type WebhookMimeType = (typeof WEBHOOK_MIME_TYPES)[number]; export type WebhookColorMode = (typeof WEBHOOK_COLOR_MODES)[number]; -/** - * @additionalProperties false - */ export interface WebhookConfig extends NotificationConfig { provider: "webhook"; /** diff --git a/schemas/config/providers.ts b/schemas/config/providers.ts index cd3e296..e049927 100644 --- a/schemas/config/providers.ts +++ b/schemas/config/providers.ts @@ -1,9 +1,6 @@ import { URI, URL } from "../types"; import { GotifyConfig, WebhookConfig } from "./notification"; -/** - * @additionalProperties false - */ export type Providers = { /** List of route definition files to include * diff --git a/schemas/docker_routes.schema.json b/schemas/docker_routes.schema.json new file mode 100644 index 0000000..dd1f1ab --- /dev/null +++ b/schemas/docker_routes.schema.json @@ -0,0 +1,1198 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "access_log": { + "additionalProperties": false, + "description": "Access log config", + "examples": [ + { + "fields": { + "headers": { + "config": { + "foo": "redact" + }, + "default": "keep" + } + }, + "filters": { + "status_codes": { + "values": [ + "200-299" + ] + } + }, + "format": "combined", + "path": "/var/log/access.log" + } + ], + "properties": { + "buffer_size": { + "default": 65536, + "description": "The size of the buffer.", + "minimum": 0, + "type": "integer" + }, + "fields": { + "additionalProperties": false, + "properties": { + "cookie": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": { + "enum": [ + "drop", + "keep", + "redact" + ], + "type": "string" + }, + "type": "object" + }, + "default": { + "$ref": "#/definitions/AccessLogFieldMode" + } + }, + "required": [ + "config" + ], + "type": "object" + }, + "header": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": { + "enum": [ + "drop", + "keep", + "redact" + ], + "type": "string" + }, + "type": "object" + }, + "default": { + "$ref": "#/definitions/AccessLogFieldMode" + } + }, + "required": [ + "config" + ], + "type": "object" + }, + "query": { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": { + "enum": [ + "drop", + "keep", + "redact" + ], + "type": "string" + }, + "type": "object" + }, + "default": { + "$ref": "#/definitions/AccessLogFieldMode" + } + }, + "required": [ + "config" + ], + "type": "object" + } + }, + "type": "object" + }, + "filters": { + "additionalProperties": false, + "properties": { + "cidr": { + "additionalProperties": false, + "properties": { + "negative": { + "default": false, + "description": "Whether the filter is negative.", + "type": "boolean" + }, + "values": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "headers": { + "additionalProperties": false, + "properties": { + "negative": { + "default": false, + "description": "Whether the filter is negative.", + "type": "boolean" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "host": { + "additionalProperties": false, + "properties": { + "negative": { + "default": false, + "description": "Whether the filter is negative.", + "type": "boolean" + }, + "values": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "method": { + "additionalProperties": false, + "properties": { + "negative": { + "default": false, + "description": "Whether the filter is negative.", + "type": "boolean" + }, + "values": { + "items": { + "enum": [ + "CONNECT", + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT", + "TRACE" + ], + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "status_code": { + "additionalProperties": false, + "properties": { + "negative": { + "default": false, + "description": "Whether the filter is negative.", + "type": "boolean" + }, + "values": { + "items": { + "$ref": "#/definitions/StatusCodeRange" + }, + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + } + }, + "type": "object" + }, + "format": { + "$ref": "#/definitions/AccessLogFormat", + "default": "combined", + "description": "The format of the access log." + }, + "path": { + "format": "uri-reference", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "alias": { + "description": "Alias (subdomain or FDN)", + "minLength": 1, + "type": "string" + }, + "healthcheck": { + "additionalProperties": false, + "description": "Healthcheck config", + "properties": { + "disable": { + "default": false, + "description": "Disable healthcheck", + "type": "boolean" + }, + "interval": { + "default": "5s", + "description": "Healthcheck interval", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "path": { + "default": "/", + "description": "Healthcheck path", + "format": "uri-reference", + "type": "string" + }, + "timeout": { + "default": "5s", + "description": "Healthcheck timeout", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "use_get": { + "default": false, + "description": "Use GET instead of HEAD", + "type": "boolean" + } + }, + "type": "object" + }, + "homepage": { + "additionalProperties": false, + "description": "Homepage config", + "examples": [ + { + "category": "Arr suite", + "icon": "png/sonarr.png", + "name": "Sonarr" + }, + { + "icon": "@target/favicon.ico", + "name": "App" + } + ], + "properties": { + "category": { + "type": "string" + }, + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + }, + "show": { + "default": true, + "description": "Whether show in dashboard", + "type": "boolean" + }, + "url": { + "format": "uri", + "type": "string" + }, + "widget_config": { + "additionalProperties": {}, + "type": "object" + } + }, + "type": "object" + }, + "host": { + "default": "localhost", + "description": "Proxy host", + "type": "string" + }, + "idle_timeout": { + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "load_balance": { + "$ref": "#/definitions/LoadBalanceConfig", + "description": "Load balance config" + }, + "middlewares": { + "$ref": "#/definitions/MiddlewaresMap", + "description": "Middlewares" + }, + "no_tls_verify": { + "default": false, + "description": "Skip TLS verification", + "type": "boolean" + }, + "path_patterns": { + "description": "Path patterns (only patterns that match will be proxied).\n\nSee https://pkg.go.dev/net/http#hdr-Patterns-ServeMux", + "items": { + "type": "string" + }, + "type": "array" + }, + "port": { + "default": 80, + "description": "Proxy port", + "maximum": 65535, + "minimum": 0, + "type": "integer" + }, + "scheme": { + "$ref": "#/definitions/ProxyScheme", + "default": "http", + "description": "Proxy scheme" + }, + "start_endpoint": { + "format": "uri-reference", + "type": "string" + }, + "stop_method": { + "$ref": "#/definitions/StopMethod", + "default": "stop", + "description": "Stop method" + }, + "stop_signal": { + "$ref": "#/definitions/Signal" + }, + "stop_timeout": { + "default": "10s", + "description": "Stop timeout", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "wake_timeout": { + "default": "30s", + "description": "Wake timeout", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + } + }, + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "alias": { + "description": "Alias (subdomain or FDN)", + "minLength": 1, + "type": "string" + }, + "healthcheck": { + "additionalProperties": false, + "description": "Healthcheck config", + "properties": { + "disable": { + "default": false, + "description": "Disable healthcheck", + "type": "boolean" + }, + "interval": { + "default": "5s", + "description": "Healthcheck interval", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "path": { + "default": "/", + "description": "Healthcheck path", + "format": "uri-reference", + "type": "string" + }, + "timeout": { + "default": "5s", + "description": "Healthcheck timeout", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "use_get": { + "default": false, + "description": "Use GET instead of HEAD", + "type": "boolean" + } + }, + "type": "object" + }, + "host": { + "default": "localhost", + "description": "Stream host", + "type": "string" + }, + "idle_timeout": { + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "port": { + "pattern": "^\\d+:\\d+$", + "type": "string" + }, + "scheme": { + "$ref": "#/definitions/StreamScheme", + "default": "tcp", + "description": "Stream scheme" + }, + "start_endpoint": { + "format": "uri-reference", + "type": "string" + }, + "stop_method": { + "$ref": "#/definitions/StopMethod", + "default": "stop", + "description": "Stop method" + }, + "stop_signal": { + "$ref": "#/definitions/Signal" + }, + "stop_timeout": { + "default": "10s", + "description": "Stop timeout", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "wake_timeout": { + "default": "30s", + "description": "Wake timeout", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + } + }, + "required": [ + "port", + "scheme" + ], + "type": "object" + } + ] + }, + "definitions": { + "AccessLogFieldMode": { + "enum": [ + "drop", + "keep", + "redact" + ], + "type": "string" + }, + "AccessLogFormat": { + "enum": [ + "combined", + "common", + "json" + ], + "type": "string" + }, + "CIDR": { + "anyOf": [ + { + "pattern": "^[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*$", + "type": "string" + }, + { + "pattern": "^.*:.*:.*:.*:.*:.*:.*:.*$", + "type": "string" + }, + { + "pattern": "^[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*/[0-9]*$", + "type": "string" + }, + { + "pattern": "^::[0-9]*$", + "type": "string" + }, + { + "pattern": "^.*::/[0-9]*$", + "type": "string" + }, + { + "pattern": "^.*:.*::/[0-9]*$", + "type": "string" + } + ] + }, + "LoadBalanceConfig": { + "additionalProperties": false, + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "link": { + "description": "Alias (subdomain or FDN) of load-balancer", + "minLength": 1, + "type": "string" + }, + "mode": { + "const": "round_robin", + "type": "string" + }, + "weight": { + "description": "Load-balance weight (reserved for future use)", + "maximum": 100, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "link", + "mode" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "link": { + "description": "Alias (subdomain or FDN) of load-balancer", + "minLength": 1, + "type": "string" + }, + "mode": { + "const": "least_conn", + "type": "string" + }, + "weight": { + "description": "Load-balance weight (reserved for future use)", + "maximum": 100, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "link", + "mode" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "config": { + "additionalProperties": false, + "description": "Real IP config, header to get client IP from", + "properties": { + "from": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + }, + "header": { + "default": "X-Real-IP", + "description": "Header to get the client IP from", + "pattern": "^[a-zA-Z0-9\\-]+$", + "type": "string" + }, + "recursive": { + "default": false, + "description": "Recursive resolve the IP", + "type": "boolean" + }, + "use": { + "enum": [ + "RealIP", + "realIP", + "real_ip" + ], + "type": "string" + } + }, + "required": [ + "from", + "use" + ], + "type": "object" + }, + "link": { + "description": "Alias (subdomain or FDN) of load-balancer", + "minLength": 1, + "type": "string" + }, + "mode": { + "const": "ip_hash", + "type": "string" + }, + "weight": { + "description": "Load-balance weight (reserved for future use)", + "maximum": 100, + "minimum": 0, + "type": "number" + } + }, + "required": [ + "config", + "link", + "mode" + ], + "type": "object" + } + ] + }, + "MiddlewaresMap": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "use": { + "pattern": "^.*@file$", + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "$ref": "#/definitions/{error_page:Omit;errorPage:Omit;ErrorPage:Omit;custom_error_page:Omit;customErrorPage:Omit;CustomErrorPage:Omit;}" + }, + { + "$ref": "#/definitions/{redirect_http:Omit;redirectHTTP:Omit;RedirectHTTP:Omit;}" + }, + { + "$ref": "#/definitions/{set_x_forwarded:Omit;setXForwarded:Omit;SetXForwarded:Omit;}" + }, + { + "$ref": "#/definitions/{hide_x_forwarded:Omit;hideXForwarded:Omit;HideXForwarded:Omit;}" + }, + { + "$ref": "#/definitions/{cidr_whitelist:Omit;cidrWhitelist:Omit;CIDRWhitelist:Omit;}" + }, + { + "$ref": "#/definitions/{cloudflare_real_ip:Omit;cloudflareRealIp:Omit;}" + }, + { + "$ref": "#/definitions/{request:Omit;Request:Omit;modify_request:Omit;modifyRequest:Omit;ModifyRequest:Omit;}" + }, + { + "$ref": "#/definitions/{response:Omit;Response:Omit;modify_response:Omit;modifyResponse:Omit;ModifyResponse:Omit;}" + }, + { + "$ref": "#/definitions/{oidc:Omit;OIDC:Omit;}" + }, + { + "$ref": "#/definitions/{rate_limit:Omit;rateLimit:Omit;RateLimit:Omit;}" + }, + { + "$ref": "#/definitions/{real_ip:Omit;realIP:Omit;RealIP:Omit;}" + }, + { + "$ref": "#/definitions/{[x:`${string}@file`]:NullOrEmptyMap;}" + } + ] + }, + "Omit": { + "additionalProperties": false, + "properties": { + "allow": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + }, + "message": { + "default": "IP not allowed", + "description": "Error message when blocked", + "type": "string" + }, + "status": { + "$ref": "#/definitions/StatusCode", + "default": 403, + "description": "HTTP status code when blocked (alias of status_code)" + }, + "status_code": { + "$ref": "#/definitions/StatusCode", + "default": 403, + "description": "HTTP status code when blocked" + } + }, + "required": [ + "allow" + ], + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "recursive": { + "default": false, + "description": "Recursively resolve the IP", + "type": "boolean" + } + }, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "add_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Add HTTP headers", + "type": "object" + }, + "hide_headers": { + "description": "Hide HTTP headers", + "items": { + "type": "string" + }, + "type": "array" + }, + "set_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Set HTTP headers", + "type": "object" + } + }, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "add_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Add HTTP headers", + "type": "object" + }, + "hide_headers": { + "description": "Hide HTTP headers", + "items": { + "type": "string" + }, + "type": "array" + }, + "set_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Set HTTP headers", + "type": "object" + } + }, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "allowed_groups": { + "description": "Allowed groups", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "allowed_users": { + "description": "Allowed users", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "average": { + "description": "Average number of requests allowed in a period", + "type": "number" + }, + "burst": { + "description": "Maximum number of requests allowed in a period", + "type": "number" + }, + "period": { + "default": "1s", + "description": "Duration of the rate limit", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + } + }, + "required": [ + "average", + "burst" + ], + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "from": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + }, + "header": { + "default": "X-Real-IP", + "description": "Header to get the client IP from", + "pattern": "^[a-zA-Z0-9\\-]+$", + "type": "string" + }, + "recursive": { + "default": false, + "description": "Recursive resolve the IP", + "type": "boolean" + } + }, + "required": [ + "from" + ], + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "type": "object" + }, + "ProxyScheme": { + "enum": [ + "http", + "https" + ], + "type": "string" + }, + "Signal": { + "enum": [ + "", + "HUP", + "INT", + "QUIT", + "SIGHUP", + "SIGINT", + "SIGQUIT", + "SIGTERM", + "TERM" + ], + "type": "string" + }, + "StatusCode": { + "anyOf": [ + { + "pattern": "^[0-9]*$", + "type": "string" + }, + { + "type": "number" + } + ] + }, + "StatusCodeRange": { + "anyOf": [ + { + "pattern": "^[0-9]*$", + "type": "string" + }, + { + "pattern": "^[0-9]*-[0-9]*$", + "type": "string" + }, + { + "type": "number" + } + ] + }, + "StopMethod": { + "enum": [ + "kill", + "pause", + "stop" + ], + "type": "string" + }, + "StreamScheme": { + "enum": [ + "tcp", + "udp" + ], + "type": "string" + }, + "{[x:`${string}@file`]:NullOrEmptyMap;}": { + "additionalProperties": false, + "type": "object" + }, + "{cidr_whitelist:Omit;cidrWhitelist:Omit;CIDRWhitelist:Omit;}": { + "additionalProperties": false, + "properties": { + "CIDRWhitelist": { + "$ref": "#/definitions/Omit" + }, + "cidrWhitelist": { + "$ref": "#/definitions/Omit" + }, + "cidr_whitelist": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "CIDRWhitelist", + "cidrWhitelist", + "cidr_whitelist" + ], + "type": "object" + }, + "{cloudflare_real_ip:Omit;cloudflareRealIp:Omit;}": { + "additionalProperties": false, + "properties": { + "cloudflareRealIp": { + "$ref": "#/definitions/Omit" + }, + "cloudflare_real_ip": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "cloudflareRealIp", + "cloudflare_real_ip" + ], + "type": "object" + }, + "{error_page:Omit;errorPage:Omit;ErrorPage:Omit;custom_error_page:Omit;customErrorPage:Omit;CustomErrorPage:Omit;}": { + "additionalProperties": false, + "properties": { + "CustomErrorPage": { + "$ref": "#/definitions/Omit" + }, + "ErrorPage": { + "$ref": "#/definitions/Omit" + }, + "customErrorPage": { + "$ref": "#/definitions/Omit" + }, + "custom_error_page": { + "$ref": "#/definitions/Omit" + }, + "errorPage": { + "$ref": "#/definitions/Omit" + }, + "error_page": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "CustomErrorPage", + "ErrorPage", + "customErrorPage", + "custom_error_page", + "errorPage", + "error_page" + ], + "type": "object" + }, + "{hide_x_forwarded:Omit;hideXForwarded:Omit;HideXForwarded:Omit;}": { + "additionalProperties": false, + "properties": { + "HideXForwarded": { + "$ref": "#/definitions/Omit" + }, + "hideXForwarded": { + "$ref": "#/definitions/Omit" + }, + "hide_x_forwarded": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "HideXForwarded", + "hideXForwarded", + "hide_x_forwarded" + ], + "type": "object" + }, + "{oidc:Omit;OIDC:Omit;}": { + "additionalProperties": false, + "properties": { + "OIDC": { + "$ref": "#/definitions/Omit" + }, + "oidc": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "OIDC", + "oidc" + ], + "type": "object" + }, + "{rate_limit:Omit;rateLimit:Omit;RateLimit:Omit;}": { + "additionalProperties": false, + "properties": { + "RateLimit": { + "$ref": "#/definitions/Omit" + }, + "rateLimit": { + "$ref": "#/definitions/Omit" + }, + "rate_limit": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "RateLimit", + "rateLimit", + "rate_limit" + ], + "type": "object" + }, + "{real_ip:Omit;realIP:Omit;RealIP:Omit;}": { + "additionalProperties": false, + "properties": { + "RealIP": { + "$ref": "#/definitions/Omit" + }, + "realIP": { + "$ref": "#/definitions/Omit" + }, + "real_ip": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "RealIP", + "realIP", + "real_ip" + ], + "type": "object" + }, + "{redirect_http:Omit;redirectHTTP:Omit;RedirectHTTP:Omit;}": { + "additionalProperties": false, + "properties": { + "RedirectHTTP": { + "$ref": "#/definitions/Omit" + }, + "redirectHTTP": { + "$ref": "#/definitions/Omit" + }, + "redirect_http": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "RedirectHTTP", + "redirectHTTP", + "redirect_http" + ], + "type": "object" + }, + "{request:Omit;Request:Omit;modify_request:Omit;modifyRequest:Omit;ModifyRequest:Omit;}": { + "additionalProperties": false, + "properties": { + "ModifyRequest": { + "$ref": "#/definitions/Omit" + }, + "Request": { + "$ref": "#/definitions/Omit" + }, + "modifyRequest": { + "$ref": "#/definitions/Omit" + }, + "modify_request": { + "$ref": "#/definitions/Omit" + }, + "request": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "ModifyRequest", + "Request", + "modifyRequest", + "modify_request", + "request" + ], + "type": "object" + }, + "{response:Omit;Response:Omit;modify_response:Omit;modifyResponse:Omit;ModifyResponse:Omit;}": { + "additionalProperties": false, + "properties": { + "ModifyResponse": { + "$ref": "#/definitions/Omit" + }, + "Response": { + "$ref": "#/definitions/Omit" + }, + "modifyResponse": { + "$ref": "#/definitions/Omit" + }, + "modify_response": { + "$ref": "#/definitions/Omit" + }, + "response": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "ModifyResponse", + "Response", + "modifyResponse", + "modify_response", + "response" + ], + "type": "object" + }, + "{set_x_forwarded:Omit;setXForwarded:Omit;SetXForwarded:Omit;}": { + "additionalProperties": false, + "properties": { + "SetXForwarded": { + "$ref": "#/definitions/Omit" + }, + "setXForwarded": { + "$ref": "#/definitions/Omit" + }, + "set_x_forwarded": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "SetXForwarded", + "setXForwarded", + "set_x_forwarded" + ], + "type": "object" + } + }, + "type": "object" +} + diff --git a/schemas/middleware_compose.schema.json b/schemas/middleware_compose.schema.json index 5017ed3..557f7a8 100644 --- a/schemas/middleware_compose.schema.json +++ b/schemas/middleware_compose.schema.json @@ -1,6 +1,5 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false, "definitions": { "CIDR": { "anyOf": [ @@ -30,126 +29,320 @@ } ] }, - "Partial": { - "properties": { - "allow": { - "items": { - "$ref": "#/definitions/CIDR" + "MiddlewareComposeMap": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "use": { + "enum": [ + "CustomErrorPage", + "ErrorPage", + "customErrorPage", + "custom_error_page", + "errorPage", + "error_page" + ], + "type": "string" + } }, - "type": "array" - }, - "message": { - "default": "IP not allowed", - "description": "Error message when blocked", - "type": "string" - }, - "status_code": { - "$ref": "#/definitions/StatusCode", - "default": 403, - "description": "HTTP status code when blocked" - } - }, - "type": "object" - }, - "Partial": { - "properties": { - "recursive": { - "default": false, - "description": "Recursively resolve the IP", - "type": "boolean" - } - }, - "type": "object" - }, - "Partial": { - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", + "required": [ + "use" + ], "type": "object" }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" + { + "additionalProperties": false, + "properties": { + "use": { + "enum": [ + "RedirectHTTP", + "redirectHTTP", + "redirect_http" + ], + "type": "string" + } }, - "type": "array" + "required": [ + "use" + ], + "type": "object" }, - "set_headers": { - "additionalProperties": { - "type": "string" + { + "additionalProperties": false, + "properties": { + "use": { + "enum": [ + "SetXForwarded", + "setXForwarded", + "set_x_forwarded" + ], + "type": "string" + } }, - "description": "Set HTTP headers", + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "use": { + "enum": [ + "HideXForwarded", + "hideXForwarded", + "hide_x_forwarded" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allow": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + }, + "message": { + "default": "IP not allowed", + "description": "Error message when blocked", + "type": "string" + }, + "status": { + "$ref": "#/definitions/StatusCode", + "default": 403, + "description": "HTTP status code when blocked (alias of status_code)" + }, + "status_code": { + "$ref": "#/definitions/StatusCode", + "default": 403, + "description": "HTTP status code when blocked" + }, + "use": { + "enum": [ + "CIDRWhitelist", + "cidrWhitelist", + "cidr_whitelist" + ], + "type": "string" + } + }, + "required": [ + "allow", + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "recursive": { + "default": false, + "description": "Recursively resolve the IP", + "type": "boolean" + }, + "use": { + "enum": [ + "cloudflareRealIp", + "cloudflare_real_ip" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "add_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Add HTTP headers", + "type": "object" + }, + "hide_headers": { + "description": "Hide HTTP headers", + "items": { + "type": "string" + }, + "type": "array" + }, + "set_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Set HTTP headers", + "type": "object" + }, + "use": { + "enum": [ + "ModifyRequest", + "Request", + "modifyRequest", + "modify_request", + "request" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "add_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Add HTTP headers", + "type": "object" + }, + "hide_headers": { + "description": "Hide HTTP headers", + "items": { + "type": "string" + }, + "type": "array" + }, + "set_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Set HTTP headers", + "type": "object" + }, + "use": { + "enum": [ + "ModifyResponse", + "Response", + "modifyResponse", + "modify_response", + "response" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "allowed_groups": { + "description": "Allowed groups", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "allowed_users": { + "description": "Allowed users", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "use": { + "enum": [ + "OIDC", + "oidc" + ], + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "average": { + "description": "Average number of requests allowed in a period", + "type": "number" + }, + "burst": { + "description": "Maximum number of requests allowed in a period", + "type": "number" + }, + "period": { + "default": "1s", + "description": "Duration of the rate limit", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + }, + "use": { + "enum": [ + "RateLimit", + "rateLimit", + "rate_limit" + ], + "type": "string" + } + }, + "required": [ + "average", + "burst", + "use" + ], + "type": "object" + }, + { + "additionalProperties": false, + "properties": { + "from": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + }, + "header": { + "default": "X-Real-IP", + "description": "Header to get the client IP from", + "pattern": "^[a-zA-Z0-9\\-]+$", + "type": "string" + }, + "recursive": { + "default": false, + "description": "Recursive resolve the IP", + "type": "boolean" + }, + "use": { + "enum": [ + "RealIP", + "realIP", + "real_ip" + ], + "type": "string" + } + }, + "required": [ + "from", + "use" + ], "type": "object" } - }, - "type": "object" - }, - "Partial": { - "type": "object" - }, - "Partial": { - "properties": { - "allowed_groups": { - "description": "Allowed groups", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - }, - "allowed_users": { - "description": "Allowed users", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" - } - }, - "type": "object" - }, - "Partial": { - "properties": { - "average": { - "description": "Average number of requests allowed in a period", - "type": "number" - }, - "burst": { - "description": "Maximum number of requests allowed in a period", - "type": "number" - }, - "period": { - "default": "1s", - "description": "Duration of the rate limit", - "pattern": "^([0-9]+(ms|s|m|h))+$", - "type": "string" - } - }, - "type": "object" - }, - "Partial": { - "properties": { - "from": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "header": { - "description": "Header to get the client IP from", - "pattern": "^[a-zA-Z0-9\\-]+$", - "type": "string" - }, - "recursive": { - "default": false, - "description": "Recursive resolve the IP", - "type": "boolean" - } - }, - "type": "object" + ] }, "StatusCode": { "anyOf": [ @@ -164,414 +357,7 @@ } }, "items": { - "anyOf": [ - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - }, - { - "allOf": [ - { - "properties": { - "use": { - "enum": [ - "CIDRWhitelist", - "CloudflareRealIP", - "CustomErrorPage", - "HideXForwarded", - "ModifyRequest", - "ModifyResponse", - "OIDC", - "RateLimit", - "RealIP", - "RedirectHTTP", - "Request", - "Response", - "SetXForwarded", - "cidrWhitelist", - "cidr_whitelist", - "cloudflareRealIP", - "cloudflare_real_ip", - "customErrorPage", - "custom_error_page", - "errorPage", - "error_page", - "hideXForwarded", - "hide_x_forwarded", - "modifyRequest", - "modifyResponse", - "modify_request", - "modify_response", - "oidc", - "rateLimit", - "rate_limit", - "realIP", - "real_ip", - "redirectHTTP", - "redirect_http", - "request", - "response", - "setXForwarded", - "set_x_forwarded" - ], - "type": "string" - } - }, - "required": [ - "use" - ], - "type": "object" - }, - { - "$ref": "#/definitions/Partial" - } - ] - } - ] + "$ref": "#/definitions/MiddlewareComposeMap" }, "type": "array" } diff --git a/schemas/middlewares/middleware_compose.ts b/schemas/middlewares/middleware_compose.ts index 9cbe83b..0bfae2d 100644 --- a/schemas/middlewares/middleware_compose.ts +++ b/schemas/middlewares/middleware_compose.ts @@ -1,11 +1,3 @@ -import { MiddlewaresMap } from "./middlewares"; +import { MiddlewareComposeMap } from "./middlewares"; -export type MiddlewareComposeConfigBase = { - use: keyof MiddlewaresMap; -}; - -/** - * @additionalProperties false - */ -export type MiddlewareComposeConfig = (MiddlewareComposeConfigBase & - Partial)[]; +export type MiddlewareCompose = MiddlewareComposeMap[]; \ No newline at end of file diff --git a/schemas/middlewares/middlewares.ts b/schemas/middlewares/middlewares.ts index 3ee098d..483fde2 100644 --- a/schemas/middlewares/middlewares.ts +++ b/schemas/middlewares/middlewares.ts @@ -1,58 +1,57 @@ import * as types from "../types"; -/** - * @additionalProperties false - */ -export type MiddlewaresMap = { - redirect_http?: RedirectHTTP; - redirectHTTP?: RedirectHTTP; - RedirectHTTP?: RedirectHTTP; - oidc?: types.Nullable; - OIDC?: types.Nullable; - request?: ModifyRequest; - Request?: ModifyRequest; - modify_request?: ModifyRequest; - modifyRequest?: ModifyRequest; - ModifyRequest?: ModifyRequest; - response?: ModifyResponse; - Response?: ModifyResponse; - modify_response?: ModifyResponse; - modifyResponse?: ModifyResponse; - ModifyResponse?: ModifyResponse; - set_x_forwarded?: SetXForwarded; - setXForwarded?: SetXForwarded; - SetXForwarded?: SetXForwarded; - hide_x_forwarded?: HideXForwarded; - hideXForwarded?: HideXForwarded; - HideXForwarded?: HideXForwarded; - error_page?: CustomErrorPage; - errorPage?: CustomErrorPage; - custom_error_page?: CustomErrorPage; - customErrorPage?: CustomErrorPage; - CustomErrorPage?: CustomErrorPage; - real_ip?: RealIP; - realIP?: RealIP; - RealIP?: RealIP; - cloudflare_real_ip?: types.Nullable; - cloudflareRealIP?: types.Nullable; - CloudflareRealIP?: types.Nullable; - rate_limit?: RateLimit; - rateLimit?: RateLimit; - RateLimit?: RateLimit; - cidr_whitelist?: CIDRWhitelist; - cidrWhitelist?: CIDRWhitelist; - CIDRWhitelist?: CIDRWhitelist; +export type MiddlewareComposeObjectRef = `${string}@file`; + +export type KeyOptMapping = { + [key in T["use"]]: Omit; +} | { use: MiddlewareComposeObjectRef }; + +export type MiddlewaresMap = ( + | KeyOptMapping + | KeyOptMapping + | KeyOptMapping + | KeyOptMapping + | KeyOptMapping + | KeyOptMapping + | KeyOptMapping + | KeyOptMapping + | KeyOptMapping + | KeyOptMapping + | KeyOptMapping + | { [key in MiddlewareComposeObjectRef]: types.NullOrEmptyMap } +); + +export type MiddlewareComposeMap = ( + | CustomErrorPage + | RedirectHTTP + | SetXForwarded + | HideXForwarded + | CIDRWhitelist + | CloudflareRealIP + | ModifyRequest + | ModifyResponse + | OIDC + | RateLimit + | RealIP +); + +export type CustomErrorPage = { + use: "error_page" | "errorPage" | "ErrorPage" | "custom_error_page" | "customErrorPage" | "CustomErrorPage"; }; -export type CustomErrorPage = types.Null; -export type RedirectHTTP = types.Null; -export type SetXForwarded = types.Null; -export type HideXForwarded = types.Null; +export type RedirectHTTP = { + use: "redirect_http" | "redirectHTTP" | "RedirectHTTP"; +}; + +export type SetXForwarded = { + use: "set_x_forwarded" | "setXForwarded" | "SetXForwarded"; +}; +export type HideXForwarded = { + use: "hide_x_forwarded" | "hideXForwarded" | "HideXForwarded"; +}; -/** - * @additionalProperties false - */ export type CIDRWhitelist = { + use: "cidr_whitelist" | "cidrWhitelist" | "CIDRWhitelist"; /* Allowed CIDRs/IPs */ allow: types.CIDR[]; /** HTTP status code when blocked @@ -60,6 +59,11 @@ export type CIDRWhitelist = { * @default 403 */ status_code?: types.StatusCode; + /** HTTP status code when blocked (alias of status_code) + * + * @default 403 + */ + status?: types.StatusCode; /** Error message when blocked * * @default "IP not allowed" @@ -67,10 +71,8 @@ export type CIDRWhitelist = { message?: string; }; -/** - * @additionalProperties false - */ export type CloudflareRealIP = { + use: "cloudflare_real_ip" | "cloudflareRealIp" | "cloudflare_real_ip"; /** Recursively resolve the IP * * @default false @@ -78,10 +80,8 @@ export type CloudflareRealIP = { recursive?: boolean; }; -/** - * @additionalProperties false - */ export type ModifyRequest = { + use: "request" | "Request" | "modify_request" | "modifyRequest" | "ModifyRequest"; /** Set HTTP headers */ set_headers?: { [key: types.HTTPHeader]: string }; /** Add HTTP headers */ @@ -90,15 +90,18 @@ export type ModifyRequest = { hide_headers?: types.HTTPHeader[]; }; -/** - * @additionalProperties false - */ -export type ModifyResponse = ModifyRequest; +export type ModifyResponse = { + use: "response" | "Response" | "modify_response" | "modifyResponse" | "ModifyResponse"; + /** Set HTTP headers */ + set_headers?: { [key: types.HTTPHeader]: string }; + /** Add HTTP headers */ + add_headers?: { [key: types.HTTPHeader]: string }; + /** Hide HTTP headers */ + hide_headers?: types.HTTPHeader[]; +}; -/** - * @additionalProperties false - */ export type OIDC = { + use: "oidc" | "OIDC"; /** Allowed users * * @minItems 1 @@ -111,10 +114,8 @@ export type OIDC = { allowed_groups?: string[]; }; -/** - * @additionalProperties false - */ export type RateLimit = { + use: "rate_limit" | "rateLimit" | "RateLimit"; /** Average number of requests allowed in a period * * @min 1 @@ -132,18 +133,17 @@ export type RateLimit = { period?: types.Duration; }; -/** - * @additionalProperties false - */ export type RealIP = { + use: "real_ip" | "realIP" | "RealIP"; /** Header to get the client IP from * + * @default "X-Real-IP" */ - header: types.HTTPHeader; + header?: types.HTTPHeader; from: types.CIDR[]; /** Recursive resolve the IP * * @default false */ - recursive: boolean; + recursive?: boolean; }; diff --git a/schemas/providers/idlewatcher.ts b/schemas/providers/idlewatcher.ts index e002737..df24bbf 100644 --- a/schemas/providers/idlewatcher.ts +++ b/schemas/providers/idlewatcher.ts @@ -14,12 +14,8 @@ export const STOP_SIGNALS = [ "HUP", "QUIT", ] as const; - export type Signal = (typeof STOP_SIGNALS)[number]; -/** - * @additionalProperties false - */ export type IdleWatcherConfig = { /* Idle timeout */ idle_timeout?: Duration; diff --git a/schemas/providers/loadbalance.ts b/schemas/providers/loadbalance.ts index 9f758bf..4d29fdf 100644 --- a/schemas/providers/loadbalance.ts +++ b/schemas/providers/loadbalance.ts @@ -5,12 +5,8 @@ export const LOAD_BALANCE_MODES = [ "least_conn", "ip_hash", ] as const; - export type LoadBalanceMode = (typeof LOAD_BALANCE_MODES)[number]; -/** - * @additionalProperties false - */ export type LoadBalanceConfigBase = { /** Alias (subdomain or FDN) of load-balancer * @@ -25,33 +21,24 @@ export type LoadBalanceConfigBase = { weight?: number; }; -/** - * @additionalProperties false - */ export type LoadBalanceConfig = LoadBalanceConfigBase & ( + | {} // linking other routes | RoundRobinLoadBalanceConfig | LeastConnLoadBalanceConfig | IPHashLoadBalanceConfig ); -/** - * @additionalProperties false - */ export type IPHashLoadBalanceConfig = { mode: "ip_hash"; /** Real IP config, header to get client IP from */ config: RealIP; }; -/** - * @additionalProperties false - */ + export type LeastConnLoadBalanceConfig = { mode: "least_conn"; }; -/** - * @additionalProperties false - */ + export type RoundRobinLoadBalanceConfig = { mode: "round_robin"; }; diff --git a/schemas/providers/routes.ts b/schemas/providers/routes.ts index 6135600..ac5d969 100644 --- a/schemas/providers/routes.ts +++ b/schemas/providers/routes.ts @@ -16,9 +16,6 @@ export type Routes = { [key: string]: Route; }; -/** - * @additionalProperties false - */ export type ReverseProxyRoute = { /** Alias (subdomain or FDN) * @minLength 1 @@ -67,9 +64,6 @@ export type ReverseProxyRoute = { access_log?: AccessLogConfig; }; -/** - * @additionalProperties false - */ export type StreamRoute = { /** Alias (subdomain or FDN) * @minLength 1 diff --git a/schemas/routes.schema.json b/schemas/routes.schema.json index 29d4c4a..e533ef2 100644 --- a/schemas/routes.schema.json +++ b/schemas/routes.schema.json @@ -52,203 +52,355 @@ "additionalProperties": false, "anyOf": [ { - "allOf": [ - { - "additionalProperties": false, - "properties": { - "link": { - "description": "Alias (subdomain or FDN) of load-balancer", - "minLength": 1, - "type": "string" - }, - "weight": { - "description": "Load-balance weight (reserved for future use)", - "maximum": 100, - "minimum": 0, - "type": "number" - } - }, - "required": [ - "link" - ], - "type": "object" + "additionalProperties": false, + "properties": { + "link": { + "description": "Alias (subdomain or FDN) of load-balancer", + "minLength": 1, + "type": "string" }, - { - "additionalProperties": false, - "properties": { - "mode": { - "enum": [ - "round_robin" - ], - "type": "string" - } - }, - "required": [ - "mode" - ], - "type": "object" + "mode": { + "const": "round_robin", + "type": "string" + }, + "weight": { + "description": "Load-balance weight (reserved for future use)", + "maximum": 100, + "minimum": 0, + "type": "number" } - ] + }, + "required": [ + "link", + "mode" + ], + "type": "object" }, { - "allOf": [ - { - "additionalProperties": false, - "properties": { - "link": { - "description": "Alias (subdomain or FDN) of load-balancer", - "minLength": 1, - "type": "string" - }, - "weight": { - "description": "Load-balance weight (reserved for future use)", - "maximum": 100, - "minimum": 0, - "type": "number" - } - }, - "required": [ - "link" - ], - "type": "object" + "additionalProperties": false, + "properties": { + "link": { + "description": "Alias (subdomain or FDN) of load-balancer", + "minLength": 1, + "type": "string" }, - { - "additionalProperties": false, - "properties": { - "mode": { - "enum": [ - "least_conn" - ], - "type": "string" - } - }, - "required": [ - "mode" - ], - "type": "object" + "mode": { + "const": "least_conn", + "type": "string" + }, + "weight": { + "description": "Load-balance weight (reserved for future use)", + "maximum": 100, + "minimum": 0, + "type": "number" } - ] + }, + "required": [ + "link", + "mode" + ], + "type": "object" }, { - "allOf": [ - { + "additionalProperties": false, + "properties": { + "config": { "additionalProperties": false, + "description": "Real IP config, header to get client IP from", "properties": { - "link": { - "description": "Alias (subdomain or FDN) of load-balancer", - "minLength": 1, - "type": "string" - }, - "weight": { - "description": "Load-balance weight (reserved for future use)", - "maximum": 100, - "minimum": 0, - "type": "number" - } - }, - "required": [ - "link" - ], - "type": "object" - }, - { - "additionalProperties": false, - "properties": { - "config": { - "additionalProperties": false, - "description": "Real IP config, header to get client IP from", - "properties": { - "from": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "header": { - "description": "Header to get the client IP from", - "pattern": "^[a-zA-Z0-9\\-]+$", - "type": "string" - }, - "recursive": { - "default": false, - "description": "Recursive resolve the IP", - "type": "boolean" - } + "from": { + "items": { + "$ref": "#/definitions/CIDR" }, - "required": [ - "from", - "header", - "recursive" - ], - "type": "object" + "type": "array" }, - "mode": { + "header": { + "default": "X-Real-IP", + "description": "Header to get the client IP from", + "pattern": "^[a-zA-Z0-9\\-]+$", + "type": "string" + }, + "recursive": { + "default": false, + "description": "Recursive resolve the IP", + "type": "boolean" + }, + "use": { "enum": [ - "ip_hash" + "RealIP", + "realIP", + "real_ip" ], "type": "string" } }, "required": [ - "config", - "mode" + "from", + "use" ], "type": "object" - } - ] - } - ] - }, - "Null": { - "type": "null" - }, - "Nullable": { - "anyOf": [ - { - "$ref": "#/definitions/Null" - }, - { - "additionalProperties": false, - "properties": { - "recursive": { - "default": false, - "description": "Recursively resolve the IP", - "type": "boolean" - } - }, - "type": "object" - } - ] - }, - "Nullable": { - "anyOf": [ - { - "$ref": "#/definitions/Null" - }, - { - "additionalProperties": false, - "properties": { - "allowed_groups": { - "description": "Allowed groups", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" }, - "allowed_users": { - "description": "Allowed users", - "items": { - "type": "string" - }, - "minItems": 1, - "type": "array" + "link": { + "description": "Alias (subdomain or FDN) of load-balancer", + "minLength": 1, + "type": "string" + }, + "mode": { + "const": "ip_hash", + "type": "string" + }, + "weight": { + "description": "Load-balance weight (reserved for future use)", + "maximum": 100, + "minimum": 0, + "type": "number" } }, + "required": [ + "config", + "link", + "mode" + ], "type": "object" } ] }, + "MiddlewaresMap": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "use": { + "pattern": "^.*@file$", + "type": "string" + } + }, + "required": [ + "use" + ], + "type": "object" + }, + { + "$ref": "#/definitions/{error_page:Omit;errorPage:Omit;ErrorPage:Omit;custom_error_page:Omit;customErrorPage:Omit;CustomErrorPage:Omit;}" + }, + { + "$ref": "#/definitions/{redirect_http:Omit;redirectHTTP:Omit;RedirectHTTP:Omit;}" + }, + { + "$ref": "#/definitions/{set_x_forwarded:Omit;setXForwarded:Omit;SetXForwarded:Omit;}" + }, + { + "$ref": "#/definitions/{hide_x_forwarded:Omit;hideXForwarded:Omit;HideXForwarded:Omit;}" + }, + { + "$ref": "#/definitions/{cidr_whitelist:Omit;cidrWhitelist:Omit;CIDRWhitelist:Omit;}" + }, + { + "$ref": "#/definitions/{cloudflare_real_ip:Omit;cloudflareRealIp:Omit;}" + }, + { + "$ref": "#/definitions/{request:Omit;Request:Omit;modify_request:Omit;modifyRequest:Omit;ModifyRequest:Omit;}" + }, + { + "$ref": "#/definitions/{response:Omit;Response:Omit;modify_response:Omit;modifyResponse:Omit;ModifyResponse:Omit;}" + }, + { + "$ref": "#/definitions/{oidc:Omit;OIDC:Omit;}" + }, + { + "$ref": "#/definitions/{rate_limit:Omit;rateLimit:Omit;RateLimit:Omit;}" + }, + { + "$ref": "#/definitions/{real_ip:Omit;realIP:Omit;RealIP:Omit;}" + }, + { + "$ref": "#/definitions/{[x:`${string}@file`]:NullOrEmptyMap;}" + } + ] + }, + "Omit": { + "additionalProperties": false, + "properties": { + "allow": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + }, + "message": { + "default": "IP not allowed", + "description": "Error message when blocked", + "type": "string" + }, + "status": { + "$ref": "#/definitions/StatusCode", + "default": 403, + "description": "HTTP status code when blocked (alias of status_code)" + }, + "status_code": { + "$ref": "#/definitions/StatusCode", + "default": 403, + "description": "HTTP status code when blocked" + } + }, + "required": [ + "allow" + ], + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "recursive": { + "default": false, + "description": "Recursively resolve the IP", + "type": "boolean" + } + }, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "add_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Add HTTP headers", + "type": "object" + }, + "hide_headers": { + "description": "Hide HTTP headers", + "items": { + "type": "string" + }, + "type": "array" + }, + "set_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Set HTTP headers", + "type": "object" + } + }, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "add_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Add HTTP headers", + "type": "object" + }, + "hide_headers": { + "description": "Hide HTTP headers", + "items": { + "type": "string" + }, + "type": "array" + }, + "set_headers": { + "additionalProperties": { + "type": "string" + }, + "description": "Set HTTP headers", + "type": "object" + } + }, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "allowed_groups": { + "description": "Allowed groups", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + }, + "allowed_users": { + "description": "Allowed users", + "items": { + "type": "string" + }, + "minItems": 1, + "type": "array" + } + }, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "average": { + "description": "Average number of requests allowed in a period", + "type": "number" + }, + "burst": { + "description": "Maximum number of requests allowed in a period", + "type": "number" + }, + "period": { + "default": "1s", + "description": "Duration of the rate limit", + "pattern": "^([0-9]+(ms|s|m|h))+$", + "type": "string" + } + }, + "required": [ + "average", + "burst" + ], + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "properties": { + "from": { + "items": { + "$ref": "#/definitions/CIDR" + }, + "type": "array" + }, + "header": { + "default": "X-Real-IP", + "description": "Header to get the client IP from", + "pattern": "^[a-zA-Z0-9\\-]+$", + "type": "string" + }, + "recursive": { + "default": false, + "description": "Recursive resolve the IP", + "type": "boolean" + } + }, + "required": [ + "from" + ], + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "type": "object" + }, + "Omit": { + "additionalProperties": false, + "type": "object" + }, "ProxyScheme": { "enum": [ "http", @@ -293,8 +445,10 @@ "type": "integer" }, "fields": { + "additionalProperties": false, "properties": { "cookie": { + "additionalProperties": false, "properties": { "config": { "additionalProperties": { @@ -317,6 +471,7 @@ "type": "object" }, "header": { + "additionalProperties": false, "properties": { "config": { "additionalProperties": { @@ -339,6 +494,7 @@ "type": "object" }, "query": { + "additionalProperties": false, "properties": { "config": { "additionalProperties": { @@ -364,8 +520,10 @@ "type": "object" }, "filters": { + "additionalProperties": false, "properties": { "cidr": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -385,6 +543,7 @@ "type": "object" }, "headers": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -404,6 +563,7 @@ "type": "object" }, "host": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -423,6 +583,7 @@ "type": "object" }, "method": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -453,6 +614,7 @@ "type": "object" }, "status_code": { + "additionalProperties": false, "properties": { "negative": { "default": false, @@ -582,566 +744,8 @@ "description": "Load balance config" }, "middlewares": { - "additionalProperties": false, - "description": "Middlewares", - "properties": { - "CIDRWhitelist": { - "additionalProperties": false, - "properties": { - "allow": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "message": { - "default": "IP not allowed", - "description": "Error message when blocked", - "type": "string" - }, - "status_code": { - "$ref": "#/definitions/StatusCode", - "default": 403, - "description": "HTTP status code when blocked" - } - }, - "required": [ - "allow" - ], - "type": "object" - }, - "CloudflareRealIP": { - "$ref": "#/definitions/Nullable" - }, - "CustomErrorPage": { - "$ref": "#/definitions/Null" - }, - "HideXForwarded": { - "$ref": "#/definitions/Null" - }, - "ModifyRequest": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "ModifyResponse": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "OIDC": { - "$ref": "#/definitions/Nullable" - }, - "RateLimit": { - "additionalProperties": false, - "properties": { - "average": { - "description": "Average number of requests allowed in a period", - "type": "number" - }, - "burst": { - "description": "Maximum number of requests allowed in a period", - "type": "number" - }, - "period": { - "default": "1s", - "description": "Duration of the rate limit", - "pattern": "^([0-9]+(ms|s|m|h))+$", - "type": "string" - } - }, - "required": [ - "average", - "burst" - ], - "type": "object" - }, - "RealIP": { - "additionalProperties": false, - "properties": { - "from": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "header": { - "description": "Header to get the client IP from", - "pattern": "^[a-zA-Z0-9\\-]+$", - "type": "string" - }, - "recursive": { - "default": false, - "description": "Recursive resolve the IP", - "type": "boolean" - } - }, - "required": [ - "from", - "header", - "recursive" - ], - "type": "object" - }, - "RedirectHTTP": { - "$ref": "#/definitions/Null" - }, - "Request": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "Response": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "SetXForwarded": { - "$ref": "#/definitions/Null" - }, - "cidrWhitelist": { - "additionalProperties": false, - "properties": { - "allow": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "message": { - "default": "IP not allowed", - "description": "Error message when blocked", - "type": "string" - }, - "status_code": { - "$ref": "#/definitions/StatusCode", - "default": 403, - "description": "HTTP status code when blocked" - } - }, - "required": [ - "allow" - ], - "type": "object" - }, - "cidr_whitelist": { - "additionalProperties": false, - "properties": { - "allow": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "message": { - "default": "IP not allowed", - "description": "Error message when blocked", - "type": "string" - }, - "status_code": { - "$ref": "#/definitions/StatusCode", - "default": 403, - "description": "HTTP status code when blocked" - } - }, - "required": [ - "allow" - ], - "type": "object" - }, - "cloudflareRealIP": { - "$ref": "#/definitions/Nullable" - }, - "cloudflare_real_ip": { - "$ref": "#/definitions/Nullable" - }, - "customErrorPage": { - "$ref": "#/definitions/Null" - }, - "custom_error_page": { - "$ref": "#/definitions/Null" - }, - "errorPage": { - "$ref": "#/definitions/Null" - }, - "error_page": { - "$ref": "#/definitions/Null" - }, - "hideXForwarded": { - "$ref": "#/definitions/Null" - }, - "hide_x_forwarded": { - "$ref": "#/definitions/Null" - }, - "modifyRequest": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "modifyResponse": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "modify_request": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "modify_response": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "oidc": { - "$ref": "#/definitions/Nullable" - }, - "rateLimit": { - "additionalProperties": false, - "properties": { - "average": { - "description": "Average number of requests allowed in a period", - "type": "number" - }, - "burst": { - "description": "Maximum number of requests allowed in a period", - "type": "number" - }, - "period": { - "default": "1s", - "description": "Duration of the rate limit", - "pattern": "^([0-9]+(ms|s|m|h))+$", - "type": "string" - } - }, - "required": [ - "average", - "burst" - ], - "type": "object" - }, - "rate_limit": { - "additionalProperties": false, - "properties": { - "average": { - "description": "Average number of requests allowed in a period", - "type": "number" - }, - "burst": { - "description": "Maximum number of requests allowed in a period", - "type": "number" - }, - "period": { - "default": "1s", - "description": "Duration of the rate limit", - "pattern": "^([0-9]+(ms|s|m|h))+$", - "type": "string" - } - }, - "required": [ - "average", - "burst" - ], - "type": "object" - }, - "realIP": { - "additionalProperties": false, - "properties": { - "from": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "header": { - "description": "Header to get the client IP from", - "pattern": "^[a-zA-Z0-9\\-]+$", - "type": "string" - }, - "recursive": { - "default": false, - "description": "Recursive resolve the IP", - "type": "boolean" - } - }, - "required": [ - "from", - "header", - "recursive" - ], - "type": "object" - }, - "real_ip": { - "additionalProperties": false, - "properties": { - "from": { - "items": { - "$ref": "#/definitions/CIDR" - }, - "type": "array" - }, - "header": { - "description": "Header to get the client IP from", - "pattern": "^[a-zA-Z0-9\\-]+$", - "type": "string" - }, - "recursive": { - "default": false, - "description": "Recursive resolve the IP", - "type": "boolean" - } - }, - "required": [ - "from", - "header", - "recursive" - ], - "type": "object" - }, - "redirectHTTP": { - "$ref": "#/definitions/Null" - }, - "redirect_http": { - "$ref": "#/definitions/Null" - }, - "request": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "response": { - "additionalProperties": false, - "properties": { - "add_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Add HTTP headers", - "type": "object" - }, - "hide_headers": { - "description": "Hide HTTP headers", - "items": { - "type": "string" - }, - "type": "array" - }, - "set_headers": { - "additionalProperties": { - "type": "string" - }, - "description": "Set HTTP headers", - "type": "object" - } - }, - "type": "object" - }, - "setXForwarded": { - "$ref": "#/definitions/Null" - }, - "set_x_forwarded": { - "$ref": "#/definitions/Null" - } - }, - "type": "object" + "$ref": "#/definitions/MiddlewaresMap", + "description": "Middlewares" }, "no_tls_verify": { "default": false, @@ -1268,6 +872,250 @@ "udp" ], "type": "string" + }, + "{[x:`${string}@file`]:NullOrEmptyMap;}": { + "additionalProperties": false, + "type": "object" + }, + "{cidr_whitelist:Omit;cidrWhitelist:Omit;CIDRWhitelist:Omit;}": { + "additionalProperties": false, + "properties": { + "CIDRWhitelist": { + "$ref": "#/definitions/Omit" + }, + "cidrWhitelist": { + "$ref": "#/definitions/Omit" + }, + "cidr_whitelist": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "CIDRWhitelist", + "cidrWhitelist", + "cidr_whitelist" + ], + "type": "object" + }, + "{cloudflare_real_ip:Omit;cloudflareRealIp:Omit;}": { + "additionalProperties": false, + "properties": { + "cloudflareRealIp": { + "$ref": "#/definitions/Omit" + }, + "cloudflare_real_ip": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "cloudflareRealIp", + "cloudflare_real_ip" + ], + "type": "object" + }, + "{error_page:Omit;errorPage:Omit;ErrorPage:Omit;custom_error_page:Omit;customErrorPage:Omit;CustomErrorPage:Omit;}": { + "additionalProperties": false, + "properties": { + "CustomErrorPage": { + "$ref": "#/definitions/Omit" + }, + "ErrorPage": { + "$ref": "#/definitions/Omit" + }, + "customErrorPage": { + "$ref": "#/definitions/Omit" + }, + "custom_error_page": { + "$ref": "#/definitions/Omit" + }, + "errorPage": { + "$ref": "#/definitions/Omit" + }, + "error_page": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "CustomErrorPage", + "ErrorPage", + "customErrorPage", + "custom_error_page", + "errorPage", + "error_page" + ], + "type": "object" + }, + "{hide_x_forwarded:Omit;hideXForwarded:Omit;HideXForwarded:Omit;}": { + "additionalProperties": false, + "properties": { + "HideXForwarded": { + "$ref": "#/definitions/Omit" + }, + "hideXForwarded": { + "$ref": "#/definitions/Omit" + }, + "hide_x_forwarded": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "HideXForwarded", + "hideXForwarded", + "hide_x_forwarded" + ], + "type": "object" + }, + "{oidc:Omit;OIDC:Omit;}": { + "additionalProperties": false, + "properties": { + "OIDC": { + "$ref": "#/definitions/Omit" + }, + "oidc": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "OIDC", + "oidc" + ], + "type": "object" + }, + "{rate_limit:Omit;rateLimit:Omit;RateLimit:Omit;}": { + "additionalProperties": false, + "properties": { + "RateLimit": { + "$ref": "#/definitions/Omit" + }, + "rateLimit": { + "$ref": "#/definitions/Omit" + }, + "rate_limit": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "RateLimit", + "rateLimit", + "rate_limit" + ], + "type": "object" + }, + "{real_ip:Omit;realIP:Omit;RealIP:Omit;}": { + "additionalProperties": false, + "properties": { + "RealIP": { + "$ref": "#/definitions/Omit" + }, + "realIP": { + "$ref": "#/definitions/Omit" + }, + "real_ip": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "RealIP", + "realIP", + "real_ip" + ], + "type": "object" + }, + "{redirect_http:Omit;redirectHTTP:Omit;RedirectHTTP:Omit;}": { + "additionalProperties": false, + "properties": { + "RedirectHTTP": { + "$ref": "#/definitions/Omit" + }, + "redirectHTTP": { + "$ref": "#/definitions/Omit" + }, + "redirect_http": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "RedirectHTTP", + "redirectHTTP", + "redirect_http" + ], + "type": "object" + }, + "{request:Omit;Request:Omit;modify_request:Omit;modifyRequest:Omit;ModifyRequest:Omit;}": { + "additionalProperties": false, + "properties": { + "ModifyRequest": { + "$ref": "#/definitions/Omit" + }, + "Request": { + "$ref": "#/definitions/Omit" + }, + "modifyRequest": { + "$ref": "#/definitions/Omit" + }, + "modify_request": { + "$ref": "#/definitions/Omit" + }, + "request": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "ModifyRequest", + "Request", + "modifyRequest", + "modify_request", + "request" + ], + "type": "object" + }, + "{response:Omit;Response:Omit;modify_response:Omit;modifyResponse:Omit;ModifyResponse:Omit;}": { + "additionalProperties": false, + "properties": { + "ModifyResponse": { + "$ref": "#/definitions/Omit" + }, + "Response": { + "$ref": "#/definitions/Omit" + }, + "modifyResponse": { + "$ref": "#/definitions/Omit" + }, + "modify_response": { + "$ref": "#/definitions/Omit" + }, + "response": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "ModifyResponse", + "Response", + "modifyResponse", + "modify_response", + "response" + ], + "type": "object" + }, + "{set_x_forwarded:Omit;setXForwarded:Omit;SetXForwarded:Omit;}": { + "additionalProperties": false, + "properties": { + "SetXForwarded": { + "$ref": "#/definitions/Omit" + }, + "setXForwarded": { + "$ref": "#/definitions/Omit" + }, + "set_x_forwarded": { + "$ref": "#/definitions/Omit" + } + }, + "required": [ + "SetXForwarded", + "setXForwarded", + "set_x_forwarded" + ], + "type": "object" } }, "type": "object" diff --git a/schemas/types.ts b/schemas/types.ts index 6a7b0db..2ed18d5 100644 --- a/schemas/types.ts +++ b/schemas/types.ts @@ -3,6 +3,7 @@ */ export interface Null {} export type Nullable = T | Null; +export type NullOrEmptyMap = {} | Null; export const HTTP_METHODS = [ "GET",