From 7e56fce4c9d2cc238a5eacf675e91a241b93328d Mon Sep 17 00:00:00 2001 From: yusing Date: Wed, 16 Apr 2025 05:46:37 +0800 Subject: [PATCH] chore: update schema and prettify, fix package.json and Makefile --- Makefile | 42 +---- schemas/Makefile | 33 ++++ schemas/bun.lock | 14 +- schemas/config/access_log.d.ts | 80 +++++---- schemas/config/autocert.d.ts | 114 +++++++----- schemas/config/config.d.ts | 85 +++++---- schemas/config/entrypoint.d.ts | 58 +++--- schemas/config/homepage.d.ts | 10 +- schemas/config/notification.d.ts | 91 +++++----- schemas/config/providers.d.ts | 75 ++++---- schemas/docker.d.ts | 2 +- schemas/docker_routes.schema.json | 2 +- schemas/index.d.ts | 21 ++- schemas/middlewares/middlewares.d.ts | 257 ++++++++++++++++----------- schemas/package.json | 19 +- schemas/providers/healthcheck.d.ts | 52 +++--- schemas/providers/homepage.d.ts | 26 +-- schemas/providers/idlewatcher.d.ts | 48 +++-- schemas/providers/loadbalance.d.ts | 46 +++-- schemas/providers/routes.d.ts | 238 +++++++++++++------------ schemas/providers/routes.ts | 14 +- schemas/routes.schema.json | 2 +- schemas/tsconfig.json | 12 +- schemas/types.d.ts | 20 ++- 24 files changed, 778 insertions(+), 583 deletions(-) create mode 100644 schemas/Makefile diff --git a/Makefile b/Makefile index 21264e2..86863e6 100755 --- a/Makefile +++ b/Makefile @@ -31,12 +31,12 @@ ifeq ($(debug), 1) else ifeq ($(pprof), 1) CGO_ENABLED = 1 GORACE = log_path=logs/pprof strip_path_prefix=$(shell pwd)/ halt_on_error=1 - BUILD_FLAGS = -tags pprof + BUILD_FLAGS += -tags pprof VERSION := ${VERSION}-pprof else CGO_ENABLED = 0 LDFLAGS += -s -w - BUILD_FLAGS = -pgo=auto -tags production + BUILD_FLAGS += -pgo=auto -tags production endif BUILD_FLAGS += -ldflags='$(LDFLAGS)' @@ -94,43 +94,5 @@ cloc: link-binary: ln -s /app/${NAME} bin/run -# To generate schema -# comment out this part from typescript-json-schema.js#L884 -# -# if (indexType.flags !== ts.TypeFlags.Number && !isIndexedObject) { -# throw new Error("Not supported: IndexSignatureDeclaration with index symbol other than a number or a string"); -# } - -gen-schema-single: - bun --bun run typescript-json-schema --noExtraProps --required --skipLibCheck --tsNodeRegister=true -o schemas/${OUT} schemas/${IN} ${CLASS} - # minify - python3 -c "import json; f=open('schemas/${OUT}', 'r'); j=json.load(f); f.close(); f=open('schemas/${OUT}', 'w'); json.dump(j, f, separators=(',', ':'));" - -gen-schema: - cd schemas && bun --bun tsc - 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 - cd .. - -publish-schema: - cd schemas && bun publish && cd .. - -update-schema-generator: - pnpm up -g typescript-json-schema - push-github: git push origin $(shell git rev-parse --abbrev-ref HEAD) \ No newline at end of file diff --git a/schemas/Makefile b/schemas/Makefile new file mode 100644 index 0000000..9ed26b3 --- /dev/null +++ b/schemas/Makefile @@ -0,0 +1,33 @@ +# To generate schema +# comment out this part from typescript-json-schema.js#L884 +# +# if (indexType.flags !== ts.TypeFlags.Number && !isIndexedObject) { +# throw new Error("Not supported: IndexSignatureDeclaration with index symbol other than a number or a string"); +# } + +gen-schema-single: + bun -bun typescript-json-schema --noExtraProps --required --skipLibCheck --tsNodeRegister=true -o "${OUT}" "${IN}" ${CLASS} + # minify + python3 -c "import json; f=open('${OUT}', 'r'); j=json.load(f); f.close(); f=open('${OUT}', 'w'); json.dump(j, f, separators=(',', ':'));" + +gen-schema: + bun -bun tsc + sed -i 's#"type": "module"#"type": "commonjs"#' package.json + 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 + sed -i 's#"type": "commonjs"#"type": "module"#' package.json + bun format:write \ No newline at end of file diff --git a/schemas/bun.lock b/schemas/bun.lock index e12e73c..d4c0376 100644 --- a/schemas/bun.lock +++ b/schemas/bun.lock @@ -2,10 +2,10 @@ "lockfileVersion": 1, "workspaces": { "": { - "name": "godoxy-types", + "name": "godoxy-schemas", "devDependencies": { - "prettier": "^3.4.2", - "typescript": "^5.7.3", + "prettier": "^3.5.3", + "typescript": "^5.8.3", "typescript-json-schema": "^0.65.1", }, }, @@ -29,9 +29,9 @@ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], - "@types/node": ["@types/node@18.19.74", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-HMwEkkifei3L605gFdV+/UwtpxP6JSzM+xFk2Ia6DNFSwSVBRh9qp5Tgf4lNFOMfPVuU0WnkcWpXZpgn5ufO4A=="], + "@types/node": ["@types/node@18.19.86", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ=="], - "acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="], + "acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="], "acorn-walk": ["acorn-walk@8.3.4", "", { "dependencies": { "acorn": "^8.11.0" } }, "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g=="], @@ -83,7 +83,7 @@ "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="], - "prettier": ["prettier@3.4.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ=="], + "prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="], "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], @@ -95,7 +95,7 @@ "ts-node": ["ts-node@10.9.2", "", { "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", "@tsconfig/node16": "^1.0.2", "acorn": "^8.4.1", "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "peerDependencies": { "@swc/core": ">=1.2.50", "@swc/wasm": ">=1.2.50", "@types/node": "*", "typescript": ">=2.7" }, "optionalPeers": ["@swc/core", "@swc/wasm"], "bin": { "ts-node": "dist/bin.js", "ts-script": "dist/bin-script-deprecated.js", "ts-node-cwd": "dist/bin-cwd.js", "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js" } }, "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ=="], - "typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="], + "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], "typescript-json-schema": ["typescript-json-schema@0.65.1", "", { "dependencies": { "@types/json-schema": "^7.0.9", "@types/node": "^18.11.9", "glob": "^7.1.7", "path-equal": "^1.2.5", "safe-stable-stringify": "^2.2.0", "ts-node": "^10.9.1", "typescript": "~5.5.0", "yargs": "^17.1.1" }, "bin": { "typescript-json-schema": "bin/typescript-json-schema" } }, "sha512-tuGH7ff2jPaUYi6as3lHyHcKpSmXIqN7/mu50x3HlYn0EHzLpmt3nplZ7EuhUkO0eqDRc9GqWNkfjgBPIS9kxg=="], diff --git a/schemas/config/access_log.d.ts b/schemas/config/access_log.d.ts index 7d3c304..7f57c49 100644 --- a/schemas/config/access_log.d.ts +++ b/schemas/config/access_log.d.ts @@ -1,49 +1,57 @@ import { CIDR, HTTPHeader, HTTPMethod, StatusCodeRange, URI } from "../types"; -export declare const ACCESS_LOG_FORMATS: readonly ["combined", "common", "json"]; +export declare const ACCESS_LOG_FORMATS: readonly [ + "combined", + "common", + "json", +]; export type AccessLogFormat = (typeof ACCESS_LOG_FORMATS)[number]; export type AccessLogConfig = { - /** - * The size of the buffer. - * - * @minimum 0 - * @default 65536 - * @TJS-type integer - */ - buffer_size?: number; - /** The format of the access log. - * - * @default "combined" - */ - format?: AccessLogFormat; - path: URI; - filters?: AccessLogFilters; - fields?: AccessLogFields; + /** + * The size of the buffer. + * + * @minimum 0 + * @default 65536 + * @TJS-type integer + */ + buffer_size?: number; + /** The format of the access log. + * + * @default "combined" + */ + format?: AccessLogFormat; + path: URI; + filters?: AccessLogFilters; + fields?: AccessLogFields; }; export type AccessLogFilter = { - /** Whether the filter is negative. - * - * @default false - */ - negative?: boolean; - values: T[]; + /** Whether the filter is negative. + * + * @default false + */ + negative?: boolean; + values: T[]; }; export type AccessLogFilters = { - status_code?: AccessLogFilter; - method?: AccessLogFilter; - host?: AccessLogFilter; - headers?: AccessLogFilter; - cidr?: AccessLogFilter; + status_code?: AccessLogFilter; + method?: AccessLogFilter; + host?: AccessLogFilter; + headers?: AccessLogFilter; + cidr?: AccessLogFilter; }; -export declare const ACCESS_LOG_FIELD_MODES: readonly ["keep", "drop", "redact"]; +export declare const ACCESS_LOG_FIELD_MODES: readonly [ + "keep", + "drop", + "redact", +]; export type AccessLogFieldMode = (typeof ACCESS_LOG_FIELD_MODES)[number]; export type AccessLogField = { - default?: AccessLogFieldMode; - config: { - [key: string]: AccessLogFieldMode; - }; + default?: AccessLogFieldMode; + config: { + [key: string]: AccessLogFieldMode; + }; }; export type AccessLogFields = { - header?: AccessLogField; - query?: AccessLogField; - cookie?: AccessLogField; + header?: AccessLogField; + query?: AccessLogField; + cookie?: AccessLogField; }; diff --git a/schemas/config/autocert.d.ts b/schemas/config/autocert.d.ts index ac7630e..702f91e 100644 --- a/schemas/config/autocert.d.ts +++ b/schemas/config/autocert.d.ts @@ -1,66 +1,88 @@ import { DomainOrWildcard, Email } from "../types"; -export declare const AUTOCERT_PROVIDERS: readonly ["local", "cloudflare", "clouddns", "duckdns", "ovh", "porkbun"]; +export declare const AUTOCERT_PROVIDERS: readonly [ + "local", + "cloudflare", + "clouddns", + "duckdns", + "ovh", + "porkbun", +]; export type AutocertProvider = (typeof AUTOCERT_PROVIDERS)[number]; -export type AutocertConfig = LocalOptions | CloudflareOptions | CloudDNSOptions | DuckDNSOptions | OVHOptionsWithAppKey | OVHOptionsWithOAuth2Config | PorkbunOptions; +export type AutocertConfig = + | LocalOptions + | CloudflareOptions + | CloudDNSOptions + | DuckDNSOptions + | OVHOptionsWithAppKey + | OVHOptionsWithOAuth2Config + | PorkbunOptions; export interface AutocertConfigBase { - email: Email; - domains: DomainOrWildcard[]; - cert_path?: string; - key_path?: string; + email: Email; + domains: DomainOrWildcard[]; + cert_path?: string; + key_path?: string; } export interface LocalOptions { - provider: "local"; - cert_path?: string; - key_path?: string; - options?: {} | null; + provider: "local"; + cert_path?: string; + key_path?: string; + options?: {} | null; } export interface CloudflareOptions extends AutocertConfigBase { - provider: "cloudflare"; - options: { - auth_token: string; - }; + provider: "cloudflare"; + options: { + auth_token: string; + }; } export interface CloudDNSOptions extends AutocertConfigBase { - provider: "clouddns"; - options: { - client_id: string; - email: Email; - password: string; - }; + provider: "clouddns"; + options: { + client_id: string; + email: Email; + password: string; + }; } export interface DuckDNSOptions extends AutocertConfigBase { - provider: "duckdns"; - options: { - token: string; - }; + provider: "duckdns"; + options: { + token: string; + }; } export interface PorkbunOptions extends AutocertConfigBase { - provider: "porkbun"; - options: { - api_key: string; - secret_api_key: string; - }; + provider: "porkbun"; + options: { + api_key: string; + secret_api_key: string; + }; } -export declare const OVH_ENDPOINTS: readonly ["ovh-eu", "ovh-ca", "ovh-us", "kimsufi-eu", "kimsufi-ca", "soyoustart-eu", "soyoustart-ca"]; +export declare const OVH_ENDPOINTS: readonly [ + "ovh-eu", + "ovh-ca", + "ovh-us", + "kimsufi-eu", + "kimsufi-ca", + "soyoustart-eu", + "soyoustart-ca", +]; export type OVHEndpoint = (typeof OVH_ENDPOINTS)[number]; export interface OVHOptionsWithAppKey extends AutocertConfigBase { - provider: "ovh"; - options: { - application_secret: string; - consumer_key: string; - api_endpoint?: OVHEndpoint; - application_key: string; - }; + provider: "ovh"; + options: { + application_secret: string; + consumer_key: string; + api_endpoint?: OVHEndpoint; + application_key: string; + }; } export interface OVHOptionsWithOAuth2Config extends AutocertConfigBase { - provider: "ovh"; - options: { - application_secret: string; - consumer_key: string; - api_endpoint?: OVHEndpoint; - oauth2_config: { - client_id: string; - client_secret: string; - }; + provider: "ovh"; + options: { + application_secret: string; + consumer_key: string; + api_endpoint?: OVHEndpoint; + oauth2_config: { + client_id: string; + client_secret: string; }; + }; } diff --git a/schemas/config/config.d.ts b/schemas/config/config.d.ts index b753f41..e88116f 100644 --- a/schemas/config/config.d.ts +++ b/schemas/config/config.d.ts @@ -4,51 +4,58 @@ import { EntrypointConfig } from "./entrypoint"; import { HomepageConfig } from "./homepage"; import { Providers } from "./providers"; export type Config = { - /** Optional autocert configuration - * - * @examples require(".").autocertExamples - */ - autocert?: AutocertConfig; - entrypoint?: EntrypointConfig; - providers: Providers; - /** Optional list of domains to match - * - * @minItems 1 - * @examples require(".").matchDomainsExamples - */ - match_domains?: DomainName[]; - homepage?: HomepageConfig; - /** - * Optional timeout before shutdown - * @default 3 - * @minimum 1 - */ - timeout_shutdown?: number; + /** Optional autocert configuration + * + * @examples require(".").autocertExamples + */ + autocert?: AutocertConfig; + entrypoint?: EntrypointConfig; + providers: Providers; + /** Optional list of domains to match + * + * @minItems 1 + * @examples require(".").matchDomainsExamples + */ + match_domains?: DomainName[]; + homepage?: HomepageConfig; + /** + * Optional timeout before shutdown + * @default 3 + * @minimum 1 + */ + timeout_shutdown?: number; }; -export declare const autocertExamples: ({ - provider: string; - email?: undefined; - domains?: undefined; - options?: undefined; -} | { - provider: string; - email: string; - domains: string[]; - options: { +export declare const autocertExamples: ( + | { + provider: string; + email?: undefined; + domains?: undefined; + options?: undefined; + } + | { + provider: string; + email: string; + domains: string[]; + options: { auth_token: string; client_id?: undefined; email?: undefined; password?: undefined; - }; -} | { - provider: string; - email: string; - domains: string[]; - options: { + }; + } + | { + provider: string; + email: string; + domains: string[]; + options: { client_id: string; email: string; password: string; auth_token?: undefined; - }; -})[]; -export declare const matchDomainsExamples: readonly ["example.com", "*.example.com"]; + }; + } +)[]; +export declare const matchDomainsExamples: readonly [ + "example.com", + "*.example.com", +]; diff --git a/schemas/config/entrypoint.d.ts b/schemas/config/entrypoint.d.ts index d436665..7584dd6 100644 --- a/schemas/config/entrypoint.d.ts +++ b/schemas/config/entrypoint.d.ts @@ -1,39 +1,49 @@ import { MiddlewareCompose } from "../middlewares/middleware_compose"; import { AccessLogConfig } from "./access_log"; export type EntrypointConfig = { - /** Entrypoint middleware configuration - * - * @examples require(".").middlewaresExamples - */ - middlewares?: MiddlewareCompose; - /** Entrypoint access log configuration - * - * @examples require(".").accessLogExamples - */ - access_log?: AccessLogConfig; + /** Entrypoint middleware configuration + * + * @examples require(".").middlewaresExamples + */ + middlewares?: MiddlewareCompose; + /** Entrypoint access log configuration + * + * @examples require(".").accessLogExamples + */ + access_log?: AccessLogConfig; }; -export declare const accessLogExamples: readonly [{ +export declare const accessLogExamples: readonly [ + { readonly path: "/var/log/access.log"; readonly format: "combined"; readonly filters: { - readonly status_codes: { - readonly values: readonly ["200-299"]; - }; + readonly status_codes: { + readonly values: readonly ["200-299"]; + }; }; readonly fields: { - readonly headers: { - readonly default: "keep"; - readonly config: { - readonly foo: "redact"; - }; + readonly headers: { + readonly default: "keep"; + readonly config: { + readonly foo: "redact"; }; + }; }; -}]; -export declare const middlewaresExamples: readonly [{ + }, +]; +export declare const middlewaresExamples: readonly [ + { readonly use: "RedirectHTTP"; -}, { + }, + { readonly use: "CIDRWhitelist"; - readonly allow: readonly ["127.0.0.1", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]; + readonly allow: readonly [ + "127.0.0.1", + "10.0.0.0/8", + "172.16.0.0/12", + "192.168.0.0/16", + ]; readonly status: 403; readonly message: "Forbidden"; -}]; + }, +]; diff --git a/schemas/config/homepage.d.ts b/schemas/config/homepage.d.ts index 0ac498d..31f783b 100644 --- a/schemas/config/homepage.d.ts +++ b/schemas/config/homepage.d.ts @@ -1,7 +1,7 @@ export type HomepageConfig = { - /** - * Use default app categories (uses docker image name) - * @default true - */ - use_default_categories: boolean; + /** + * Use default app categories (uses docker image name) + * @default true + */ + use_default_categories: boolean; }; diff --git a/schemas/config/notification.d.ts b/schemas/config/notification.d.ts index 0cf8610..8bf6552 100644 --- a/schemas/config/notification.d.ts +++ b/schemas/config/notification.d.ts @@ -1,60 +1,69 @@ import { URL } from "../types"; -export declare const NOTIFICATION_PROVIDERS: readonly ["webhook", "gotify", "ntfy"]; +export declare const NOTIFICATION_PROVIDERS: readonly [ + "webhook", + "gotify", + "ntfy", +]; export type NotificationProvider = (typeof NOTIFICATION_PROVIDERS)[number]; export type NotificationConfig = { - name: string; - url: URL; + name: string; + url: URL; }; export interface GotifyConfig extends NotificationConfig { - provider: "gotify"; - token: string; + provider: "gotify"; + token: string; } export declare const NTFY_MSG_STYLES: string[]; export type NtfyStyle = (typeof NTFY_MSG_STYLES)[number]; export interface NtfyConfig extends NotificationConfig { - provider: "ntfy"; - topic: string; - token?: string; - style?: NtfyStyle; + provider: "ntfy"; + topic: string; + token?: string; + style?: NtfyStyle; } export declare const WEBHOOK_TEMPLATES: readonly ["", "discord"]; export declare const WEBHOOK_METHODS: readonly ["POST", "GET", "PUT"]; -export declare const WEBHOOK_MIME_TYPES: readonly ["application/json", "application/x-www-form-urlencoded", "text/plain", "text/markdown"]; +export declare const WEBHOOK_MIME_TYPES: readonly [ + "application/json", + "application/x-www-form-urlencoded", + "text/plain", + "text/markdown", +]; export declare const WEBHOOK_COLOR_MODES: readonly ["hex", "dec"]; export type WebhookTemplate = (typeof WEBHOOK_TEMPLATES)[number]; export type WebhookMethod = (typeof WEBHOOK_METHODS)[number]; export type WebhookMimeType = (typeof WEBHOOK_MIME_TYPES)[number]; export type WebhookColorMode = (typeof WEBHOOK_COLOR_MODES)[number]; export interface WebhookConfig extends NotificationConfig { - provider: "webhook"; - /** - * Webhook template - * - * @default "discord" - */ - template?: WebhookTemplate; - token?: string; - /** - * Webhook message (usally JSON), - * required when template is not defined - */ - payload?: string; - /** - * Webhook method - * - * @default "POST" - */ - method?: WebhookMethod; - /** - * Webhook mime type - * - * @default "application/json" - */ - mime_type?: WebhookMimeType; - /** - * Webhook color mode - * - * @default "hex" - */ - color_mode?: WebhookColorMode; + provider: "webhook"; + /** + * Webhook template + * + * @default "discord" + */ + template?: WebhookTemplate; + token?: string; + /** + * Webhook message (usally JSON), + * required when template is not defined + */ + payload?: string; + /** + * Webhook method + * + * @default "POST" + */ + method?: WebhookMethod; + /** + * Webhook mime type + * + * @default "application/json" + */ + mime_type?: WebhookMimeType; + /** + * Webhook color mode + * + * @default "hex" + */ + color_mode?: WebhookColorMode; } diff --git a/schemas/config/providers.d.ts b/schemas/config/providers.d.ts index ad2816f..c91d083 100644 --- a/schemas/config/providers.d.ts +++ b/schemas/config/providers.d.ts @@ -1,51 +1,58 @@ import { URI, URL } from "../types"; import { GotifyConfig, NtfyConfig, WebhookConfig } from "./notification"; export type Providers = { - /** List of route definition files to include - * - * @minItems 1 - * @examples require(".").includeExamples - * @items.pattern ^[\w\d\-_]+\.(yaml|yml)$ - */ - include?: URI[]; - /** Name-value mapping of docker hosts to retrieve routes from - * - * @minProperties 1 - * @examples require(".").dockerExamples - */ - docker?: { - [name: string]: URL | "$DOCKER_HOST"; - }; - /** List of GoDoxy agents - * - * @minItems 1 - * @examples require(".").agentExamples - */ - agents?: `${string}:${number}`[]; - /** List of notification providers - * - * @minItems 1 - * @examples require(".").notificationExamples - */ - notification?: (WebhookConfig | GotifyConfig | NtfyConfig)[]; + /** List of route definition files to include + * + * @minItems 1 + * @examples require(".").includeExamples + * @items.pattern ^[\w\d\-_]+\.(yaml|yml)$ + */ + include?: URI[]; + /** Name-value mapping of docker hosts to retrieve routes from + * + * @minProperties 1 + * @examples require(".").dockerExamples + */ + docker?: { + [name: string]: URL | "$DOCKER_HOST"; + }; + /** List of GoDoxy agents + * + * @minItems 1 + * @examples require(".").agentExamples + */ + agents?: `${string}:${number}`[]; + /** List of notification providers + * + * @minItems 1 + * @examples require(".").notificationExamples + */ + notification?: (WebhookConfig | GotifyConfig | NtfyConfig)[]; }; export declare const includeExamples: readonly ["file1.yml", "file2.yml"]; -export declare const dockerExamples: readonly [{ +export declare const dockerExamples: readonly [ + { readonly local: "$DOCKER_HOST"; -}, { + }, + { readonly remote: "tcp://10.0.2.1:2375"; -}, { + }, + { readonly remote2: "ssh://root:1234@10.0.2.2"; -}]; -export declare const notificationExamples: readonly [{ + }, +]; +export declare const notificationExamples: readonly [ + { readonly name: "gotify"; readonly provider: "gotify"; readonly url: "https://gotify.domain.tld"; readonly token: "abcd"; -}, { + }, + { readonly name: "discord"; readonly provider: "webhook"; readonly template: "discord"; readonly url: "https://discord.com/api/webhooks/1234/abcd"; -}]; + }, +]; export declare const agentExamples: readonly ["10.0.2.3:8890", "10.0.2.4:8890"]; diff --git a/schemas/docker.d.ts b/schemas/docker.d.ts index 3b3c06d..02884ad 100644 --- a/schemas/docker.d.ts +++ b/schemas/docker.d.ts @@ -1,5 +1,5 @@ import { IdleWatcherConfig } from "./providers/idlewatcher"; import { Route } from "./providers/routes"; export type DockerRoutes = { - [key: string]: Route & IdleWatcherConfig; + [key: string]: Route & IdleWatcherConfig; }; diff --git a/schemas/docker_routes.schema.json b/schemas/docker_routes.schema.json index 26fe7fb..32025ef 100644 --- a/schemas/docker_routes.schema.json +++ b/schemas/docker_routes.schema.json @@ -1 +1 @@ -{"$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":{"$ref":"#/definitions/HTTPHeader"},"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":{"$ref":"#/definitions/URI"}},"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"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":{"anyOf":[{"format":"uri","type":"string"},{"description":"Walkxcode icon","pattern":"^(png|svg|webp)\\/[\\w\\d\\-_]+\\.\\1","type":"string"},{"pattern":"^@selfhst/.*\\..*$","type":"string"},{"pattern":"^@walkxcode/.*\\..*$","type":"string"},{"pattern":"^@target/.*$","type":"string"},{"pattern":"^/.*$","type":"string"}]},"name":{"type":"string"},"show":{"default":true,"description":"Whether show in dashboard","type":"boolean"},"url":{"$ref":"#/definitions/URL"},"widget_config":{"additionalProperties":{},"type":"object"}},"type":"object"},"host":{"anyOf":[{"format":"hostname","type":"string"},{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}],"default":"localhost","description":"Proxy host"},"idle_timeout":{"$ref":"#/definitions/Duration"},"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":{"$ref":"#/definitions/PathPattern"},"type":"array"},"port":{"$ref":"#/definitions/Port","default":80,"description":"Proxy port"},"response_header_timeout":{"$ref":"#/definitions/Duration","default":"60s","description":"Response header timeout"},"scheme":{"$ref":"#/definitions/ProxyScheme","default":"http","description":"Proxy scheme"},"start_endpoint":{"$ref":"#/definitions/URI"},"stop_method":{"$ref":"#/definitions/StopMethod","default":"stop","description":"Stop method"},"stop_signal":{"$ref":"#/definitions/Signal"},"stop_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Stop timeout"},"wake_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Wake timeout"}},"type":"object"},{"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":{"$ref":"#/definitions/HTTPHeader"},"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":{"$ref":"#/definitions/URI"}},"required":["path"],"type":"object"},"alias":{"description":"Alias (subdomain or FDN)","minLength":1,"type":"string"},"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":{"anyOf":[{"format":"uri","type":"string"},{"description":"Walkxcode icon","pattern":"^(png|svg|webp)\\/[\\w\\d\\-_]+\\.\\1","type":"string"},{"pattern":"^@selfhst/.*\\..*$","type":"string"},{"pattern":"^@walkxcode/.*\\..*$","type":"string"},{"pattern":"^@target/.*$","type":"string"},{"pattern":"^/.*$","type":"string"}]},"name":{"type":"string"},"show":{"default":true,"description":"Whether show in dashboard","type":"boolean"},"url":{"$ref":"#/definitions/URL"},"widget_config":{"additionalProperties":{},"type":"object"}},"type":"object"},"idle_timeout":{"$ref":"#/definitions/Duration"},"middlewares":{"$ref":"#/definitions/MiddlewaresMap","description":"Middlewares"},"path_patterns":{"description":"Path patterns (only patterns that match will be proxied).\n\nSee https://pkg.go.dev/net/http#hdr-Patterns-ServeMux","items":{"$ref":"#/definitions/PathPattern"},"type":"array"},"root":{"type":"string"},"scheme":{"const":"fileserver","type":"string"},"start_endpoint":{"$ref":"#/definitions/URI"},"stop_method":{"$ref":"#/definitions/StopMethod","default":"stop","description":"Stop method"},"stop_signal":{"$ref":"#/definitions/Signal"},"stop_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Stop timeout"},"wake_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Wake timeout"}},"required":["root","scheme"],"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"use_get":{"default":false,"description":"Use GET instead of HEAD","type":"boolean"}},"type":"object"},"host":{"anyOf":[{"format":"hostname","type":"string"},{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}],"default":"localhost","description":"Stream host"},"idle_timeout":{"$ref":"#/definitions/Duration"},"port":{"$ref":"#/definitions/StreamPort"},"scheme":{"$ref":"#/definitions/StreamScheme","default":"tcp","description":"Stream scheme"},"start_endpoint":{"$ref":"#/definitions/URI"},"stop_method":{"$ref":"#/definitions/StopMethod","default":"stop","description":"Stop method"},"stop_signal":{"$ref":"#/definitions/Signal"},"stop_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Stop timeout"},"wake_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Wake timeout"}},"required":["port"],"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"}]},"Duration":{"pattern":"^([0-9]+(ms|s|m|h))+$","type":"string"},"HTTPHeader":{"description":"HTTP Header","pattern":"^[a-zA-Z0-9\\-]+$","type":"string"},"LoadBalanceConfig":{"anyOf":[{"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"},"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":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"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":{"CIDRWhitelist":{"$ref":"#/definitions/Omit"},"CloudflareRealIP":{"$ref":"#/definitions/Omit"},"CustomErrorPage":{"$ref":"#/definitions/Omit"},"ErrorPage":{"$ref":"#/definitions/Omit"},"HideXForwarded":{"$ref":"#/definitions/Omit"},"ModifyRequest":{"$ref":"#/definitions/Omit"},"ModifyResponse":{"$ref":"#/definitions/Omit"},"OIDC":{"$ref":"#/definitions/Omit"},"RateLimit":{"$ref":"#/definitions/Omit"},"RealIP":{"$ref":"#/definitions/Omit"},"RedirectHTTP":{"$ref":"#/definitions/Omit"},"Request":{"$ref":"#/definitions/Omit"},"Response":{"$ref":"#/definitions/Omit"},"SetXForwarded":{"$ref":"#/definitions/Omit"},"cidrWhitelist":{"$ref":"#/definitions/Omit"},"cidr_whitelist":{"$ref":"#/definitions/Omit"},"cloudflareRealIp":{"$ref":"#/definitions/Omit"},"cloudflare_real_ip":{"$ref":"#/definitions/Omit"},"customErrorPage":{"$ref":"#/definitions/Omit"},"custom_error_page":{"$ref":"#/definitions/Omit"},"errorPage":{"$ref":"#/definitions/Omit"},"error_page":{"$ref":"#/definitions/Omit"},"hideXForwarded":{"$ref":"#/definitions/Omit"},"hide_x_forwarded":{"$ref":"#/definitions/Omit"},"modifyRequest":{"$ref":"#/definitions/Omit"},"modifyResponse":{"$ref":"#/definitions/Omit"},"modify_request":{"$ref":"#/definitions/Omit"},"modify_response":{"$ref":"#/definitions/Omit"},"oidc":{"$ref":"#/definitions/Omit"},"rateLimit":{"$ref":"#/definitions/Omit"},"rate_limit":{"$ref":"#/definitions/Omit"},"realIP":{"$ref":"#/definitions/Omit"},"real_ip":{"$ref":"#/definitions/Omit"},"redirectHTTP":{"$ref":"#/definitions/Omit"},"redirect_http":{"$ref":"#/definitions/Omit"},"request":{"$ref":"#/definitions/Omit"},"response":{"$ref":"#/definitions/Omit"},"setXForwarded":{"$ref":"#/definitions/Omit"},"set_x_forwarded":{"$ref":"#/definitions/Omit"}},"type":"object"},{"type":"object"}]},"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":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"add_prefix":{"description":"Add prefix to request URL","type":"string"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"}},"type":"object"},"Omit":{"additionalProperties":false,"properties":{"add_headers":{"additionalProperties":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"}},"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":{"$ref":"#/definitions/Duration","default":"1s","description":"Duration of the rate limit"}},"required":["average","burst"],"type":"object"},"Omit":{"additionalProperties":false,"properties":{"from":{"items":{"$ref":"#/definitions/CIDR"},"type":"array"},"header":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"recursive":{"default":false,"description":"Recursive resolve the IP","type":"boolean"}},"required":["from"],"type":"object"},"Omit":{"additionalProperties":false,"properties":{"bypass":{"additionalProperties":false,"description":"Bypass redirect","properties":{"user_agents":{"description":"Bypass redirect for user agents","items":{"type":"string"},"type":"array"}},"type":"object"}},"type":"object"},"Omit":{"additionalProperties":false,"type":"object"},"PathPattern":{"pattern":"^(?:([A-Z]+) )?(?:([a-zA-Z0-9.-]+)\\\\/)?(\\\\/[^\\\\s]*)$","type":"string"},"Port":{"maximum":65535,"minimum":0,"type":"integer"},"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"},"StreamPort":{"pattern":"^\\d+:\\d+$","type":"string"},"StreamScheme":{"enum":["tcp","udp"],"type":"string"},"URI":{"format":"uri-reference","type":"string"},"URL":{"format":"uri","type":"string"}},"type":"object"} \ No newline at end of file +{"$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":{"$ref":"#/definitions/HTTPHeader"},"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":{"$ref":"#/definitions/URI"}},"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"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":{"anyOf":[{"format":"uri","type":"string"},{"description":"Walkxcode icon","pattern":"^(png|svg|webp)\\/[\\w\\d\\-_]+\\.\\1","type":"string"},{"pattern":"^@selfhst/.*\\..*$","type":"string"},{"pattern":"^@walkxcode/.*\\..*$","type":"string"},{"pattern":"^@target/.*$","type":"string"},{"pattern":"^/.*$","type":"string"}]},"name":{"type":"string"},"show":{"default":true,"description":"Whether show in dashboard","type":"boolean"},"url":{"$ref":"#/definitions/URL"},"widget_config":{"additionalProperties":{},"type":"object"}},"type":"object"},"host":{"anyOf":[{"format":"hostname","type":"string"},{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}],"default":"localhost","description":"Proxy host"},"idle_timeout":{"$ref":"#/definitions/Duration"},"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":{"$ref":"#/definitions/PathPattern"},"type":"array"},"port":{"$ref":"#/definitions/Port","default":80,"description":"Proxy port"},"response_header_timeout":{"$ref":"#/definitions/Duration","default":"60s","description":"Response header timeout"},"scheme":{"$ref":"#/definitions/ProxyScheme","default":"http","description":"Proxy scheme"},"start_endpoint":{"$ref":"#/definitions/URI"},"stop_method":{"$ref":"#/definitions/StopMethod","default":"stop","description":"Stop method"},"stop_signal":{"$ref":"#/definitions/Signal"},"stop_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Stop timeout"},"wake_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Wake timeout"}},"type":"object"},{"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":{"$ref":"#/definitions/HTTPHeader"},"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":{"$ref":"#/definitions/URI"}},"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"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":{"anyOf":[{"format":"uri","type":"string"},{"description":"Walkxcode icon","pattern":"^(png|svg|webp)\\/[\\w\\d\\-_]+\\.\\1","type":"string"},{"pattern":"^@selfhst/.*\\..*$","type":"string"},{"pattern":"^@walkxcode/.*\\..*$","type":"string"},{"pattern":"^@target/.*$","type":"string"},{"pattern":"^/.*$","type":"string"}]},"name":{"type":"string"},"show":{"default":true,"description":"Whether show in dashboard","type":"boolean"},"url":{"$ref":"#/definitions/URL"},"widget_config":{"additionalProperties":{},"type":"object"}},"type":"object"},"idle_timeout":{"$ref":"#/definitions/Duration"},"middlewares":{"$ref":"#/definitions/MiddlewaresMap","description":"Middlewares"},"path_patterns":{"description":"Path patterns (only patterns that match will be proxied).\n\nSee https://pkg.go.dev/net/http#hdr-Patterns-ServeMux","items":{"$ref":"#/definitions/PathPattern"},"type":"array"},"root":{"type":"string"},"scheme":{"const":"fileserver","type":"string"},"start_endpoint":{"$ref":"#/definitions/URI"},"stop_method":{"$ref":"#/definitions/StopMethod","default":"stop","description":"Stop method"},"stop_signal":{"$ref":"#/definitions/Signal"},"stop_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Stop timeout"},"wake_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Wake timeout"}},"required":["root","scheme"],"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"use_get":{"default":false,"description":"Use GET instead of HEAD","type":"boolean"}},"type":"object"},"host":{"anyOf":[{"format":"hostname","type":"string"},{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}],"default":"localhost","description":"Stream host"},"idle_timeout":{"$ref":"#/definitions/Duration"},"port":{"$ref":"#/definitions/StreamPort"},"scheme":{"$ref":"#/definitions/StreamScheme","default":"tcp","description":"Stream scheme"},"start_endpoint":{"$ref":"#/definitions/URI"},"stop_method":{"$ref":"#/definitions/StopMethod","default":"stop","description":"Stop method"},"stop_signal":{"$ref":"#/definitions/Signal"},"stop_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Stop timeout"},"wake_timeout":{"$ref":"#/definitions/Duration","default":"30s","description":"Wake timeout"}},"required":["port"],"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"}]},"Duration":{"pattern":"^([0-9]+(ms|s|m|h))+$","type":"string"},"HTTPHeader":{"description":"HTTP Header","pattern":"^[a-zA-Z0-9\\-]+$","type":"string"},"LoadBalanceConfig":{"anyOf":[{"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"},"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":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"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":{"CIDRWhitelist":{"$ref":"#/definitions/Omit"},"CloudflareRealIP":{"$ref":"#/definitions/Omit"},"CustomErrorPage":{"$ref":"#/definitions/Omit"},"ErrorPage":{"$ref":"#/definitions/Omit"},"HideXForwarded":{"$ref":"#/definitions/Omit"},"ModifyRequest":{"$ref":"#/definitions/Omit"},"ModifyResponse":{"$ref":"#/definitions/Omit"},"OIDC":{"$ref":"#/definitions/Omit"},"RateLimit":{"$ref":"#/definitions/Omit"},"RealIP":{"$ref":"#/definitions/Omit"},"RedirectHTTP":{"$ref":"#/definitions/Omit"},"Request":{"$ref":"#/definitions/Omit"},"Response":{"$ref":"#/definitions/Omit"},"SetXForwarded":{"$ref":"#/definitions/Omit"},"cidrWhitelist":{"$ref":"#/definitions/Omit"},"cidr_whitelist":{"$ref":"#/definitions/Omit"},"cloudflareRealIp":{"$ref":"#/definitions/Omit"},"cloudflare_real_ip":{"$ref":"#/definitions/Omit"},"customErrorPage":{"$ref":"#/definitions/Omit"},"custom_error_page":{"$ref":"#/definitions/Omit"},"errorPage":{"$ref":"#/definitions/Omit"},"error_page":{"$ref":"#/definitions/Omit"},"hideXForwarded":{"$ref":"#/definitions/Omit"},"hide_x_forwarded":{"$ref":"#/definitions/Omit"},"modifyRequest":{"$ref":"#/definitions/Omit"},"modifyResponse":{"$ref":"#/definitions/Omit"},"modify_request":{"$ref":"#/definitions/Omit"},"modify_response":{"$ref":"#/definitions/Omit"},"oidc":{"$ref":"#/definitions/Omit"},"rateLimit":{"$ref":"#/definitions/Omit"},"rate_limit":{"$ref":"#/definitions/Omit"},"realIP":{"$ref":"#/definitions/Omit"},"real_ip":{"$ref":"#/definitions/Omit"},"redirectHTTP":{"$ref":"#/definitions/Omit"},"redirect_http":{"$ref":"#/definitions/Omit"},"request":{"$ref":"#/definitions/Omit"},"response":{"$ref":"#/definitions/Omit"},"setXForwarded":{"$ref":"#/definitions/Omit"},"set_x_forwarded":{"$ref":"#/definitions/Omit"}},"type":"object"},{"type":"object"}]},"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":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"add_prefix":{"description":"Add prefix to request URL","type":"string"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"}},"type":"object"},"Omit":{"additionalProperties":false,"properties":{"add_headers":{"additionalProperties":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"}},"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":{"$ref":"#/definitions/Duration","default":"1s","description":"Duration of the rate limit"}},"required":["average","burst"],"type":"object"},"Omit":{"additionalProperties":false,"properties":{"from":{"items":{"$ref":"#/definitions/CIDR"},"type":"array"},"header":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"recursive":{"default":false,"description":"Recursive resolve the IP","type":"boolean"}},"required":["from"],"type":"object"},"Omit":{"additionalProperties":false,"properties":{"bypass":{"additionalProperties":false,"description":"Bypass redirect","properties":{"user_agents":{"description":"Bypass redirect for user agents","items":{"type":"string"},"type":"array"}},"type":"object"}},"type":"object"},"Omit":{"additionalProperties":false,"type":"object"},"PathPattern":{"pattern":"^(?:([A-Z]+) )?(?:([a-zA-Z0-9.-]+)\\\\/)?(\\\\/[^\\\\s]*)$","type":"string"},"Port":{"maximum":65535,"minimum":0,"type":"integer"},"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"},"StreamPort":{"pattern":"^\\d+:\\d+$","type":"string"},"StreamScheme":{"enum":["tcp","udp"],"type":"string"},"URI":{"format":"uri-reference","type":"string"},"URL":{"format":"uri","type":"string"}},"type":"object"} \ No newline at end of file diff --git a/schemas/index.d.ts b/schemas/index.d.ts index 0582c30..f078530 100644 --- a/schemas/index.d.ts +++ b/schemas/index.d.ts @@ -16,4 +16,23 @@ import ConfigSchema from "./config.schema.json"; import DockerRoutesSchema from "./docker_routes.schema.json"; import MiddlewareComposeSchema from "./middleware_compose.schema.json"; import RoutesSchema from "./routes.schema.json"; -export { AccessLog, Autocert, Config, ConfigSchema, DockerRoutesSchema, Entrypoint, GoDoxy, Healthcheck, Homepage, IdleWatcher, LoadBalance, MiddlewareCompose, MiddlewareComposeSchema, Middlewares, Notification, Providers, Routes, RoutesSchema, }; +export { + AccessLog, + Autocert, + Config, + ConfigSchema, + DockerRoutesSchema, + Entrypoint, + GoDoxy, + Healthcheck, + Homepage, + IdleWatcher, + LoadBalance, + MiddlewareCompose, + MiddlewareComposeSchema, + Middlewares, + Notification, + Providers, + Routes, + RoutesSchema, +}; diff --git a/schemas/middlewares/middlewares.d.ts b/schemas/middlewares/middlewares.d.ts index c7ad0c5..4a0df0d 100644 --- a/schemas/middlewares/middlewares.d.ts +++ b/schemas/middlewares/middlewares.d.ts @@ -1,133 +1,186 @@ import * as types from "../types"; -export type KeyOptMapping = { - [key in T["use"]]?: Omit; + }, +> = { + [key in T["use"]]?: Omit; }; -export declare const ALL_MIDDLEWARES: readonly ["ErrorPage", "RedirectHTTP", "SetXForwarded", "HideXForwarded", "CIDRWhitelist", "CloudflareRealIP", "ModifyRequest", "ModifyResponse", "OIDC", "RateLimit", "RealIP"]; +export declare const ALL_MIDDLEWARES: readonly [ + "ErrorPage", + "RedirectHTTP", + "SetXForwarded", + "HideXForwarded", + "CIDRWhitelist", + "CloudflareRealIP", + "ModifyRequest", + "ModifyResponse", + "OIDC", + "RateLimit", + "RealIP", +]; /** * @type object * @patternProperties {"^.*@file$": {"type": "null"}} */ export type MiddlewareFileRef = { - [key: `${string}@file`]: null; + [key: `${string}@file`]: null; }; -export type MiddlewaresMap = (KeyOptMapping & KeyOptMapping & KeyOptMapping & KeyOptMapping & KeyOptMapping & KeyOptMapping & KeyOptMapping & KeyOptMapping & KeyOptMapping & KeyOptMapping & KeyOptMapping) | MiddlewareFileRef; -export type MiddlewareComposeMap = CustomErrorPage | RedirectHTTP | SetXForwarded | HideXForwarded | CIDRWhitelist | CloudflareRealIP | ModifyRequest | ModifyResponse | OIDC | RateLimit | RealIP; +export type MiddlewaresMap = + | (KeyOptMapping & + KeyOptMapping & + KeyOptMapping & + KeyOptMapping & + KeyOptMapping & + KeyOptMapping & + KeyOptMapping & + KeyOptMapping & + KeyOptMapping & + KeyOptMapping & + KeyOptMapping) + | MiddlewareFileRef; +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"; + use: + | "error_page" + | "errorPage" + | "ErrorPage" + | "custom_error_page" + | "customErrorPage" + | "CustomErrorPage"; }; export type RedirectHTTP = { - use: "redirect_http" | "redirectHTTP" | "RedirectHTTP"; - /** Bypass redirect */ - bypass?: { - /** Bypass redirect for user agents */ - user_agents?: string[]; - }; + use: "redirect_http" | "redirectHTTP" | "RedirectHTTP"; + /** Bypass redirect */ + bypass?: { + /** Bypass redirect for user agents */ + user_agents?: string[]; + }; }; export type SetXForwarded = { - use: "set_x_forwarded" | "setXForwarded" | "SetXForwarded"; + use: "set_x_forwarded" | "setXForwarded" | "SetXForwarded"; }; export type HideXForwarded = { - use: "hide_x_forwarded" | "hideXForwarded" | "HideXForwarded"; + use: "hide_x_forwarded" | "hideXForwarded" | "HideXForwarded"; }; export type CIDRWhitelist = { - use: "cidr_whitelist" | "cidrWhitelist" | "CIDRWhitelist"; - allow: types.CIDR[]; - /** HTTP status code when blocked - * - * @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" - */ - message?: string; + use: "cidr_whitelist" | "cidrWhitelist" | "CIDRWhitelist"; + allow: types.CIDR[]; + /** HTTP status code when blocked + * + * @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" + */ + message?: string; }; export type CloudflareRealIP = { - use: "cloudflare_real_ip" | "cloudflareRealIp" | "CloudflareRealIP"; - /** Recursively resolve the IP - * - * @default false - */ - recursive?: boolean; + use: "cloudflare_real_ip" | "cloudflareRealIp" | "CloudflareRealIP"; + /** Recursively resolve the IP + * + * @default false + */ + recursive?: boolean; }; export type ModifyRequest = { - use: "request" | "Request" | "modify_request" | "modifyRequest" | "ModifyRequest"; - /** 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[]; - /** Add prefix to request URL */ - add_prefix?: string; + use: + | "request" + | "Request" + | "modify_request" + | "modifyRequest" + | "ModifyRequest"; + /** 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[]; + /** Add prefix to request URL */ + add_prefix?: string; }; 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[]; + 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[]; }; export type OIDC = { - use: "oidc" | "OIDC"; - /** Allowed users - * - * @minItems 1 - */ - allowed_users?: string[]; - /** Allowed groups - * - * @minItems 1 - */ - allowed_groups?: string[]; + use: "oidc" | "OIDC"; + /** Allowed users + * + * @minItems 1 + */ + allowed_users?: string[]; + /** Allowed groups + * + * @minItems 1 + */ + allowed_groups?: string[]; }; export type RateLimit = { - use: "rate_limit" | "rateLimit" | "RateLimit"; - /** Average number of requests allowed in a period - * - * @min 1 - */ - average: number; - /** Maximum number of requests allowed in a period - * - * @min 1 - */ - burst: number; - /** Duration of the rate limit - * - * @default 1s - */ - period?: types.Duration; + use: "rate_limit" | "rateLimit" | "RateLimit"; + /** Average number of requests allowed in a period + * + * @min 1 + */ + average: number; + /** Maximum number of requests allowed in a period + * + * @min 1 + */ + burst: number; + /** Duration of the rate limit + * + * @default 1s + */ + period?: types.Duration; }; export type RealIP = { - use: "real_ip" | "realIP" | "RealIP"; - /** Header to get the client IP from - * - * @default "X-Real-IP" - */ - header?: types.HTTPHeader; - from: types.CIDR[]; - /** Recursive resolve the IP - * - * @default false - */ - recursive?: boolean; + use: "real_ip" | "realIP" | "RealIP"; + /** Header to get the client IP from + * + * @default "X-Real-IP" + */ + header?: types.HTTPHeader; + from: types.CIDR[]; + /** Recursive resolve the IP + * + * @default false + */ + recursive?: boolean; }; diff --git a/schemas/package.json b/schemas/package.json index 5a34c4f..1ca9a19 100644 --- a/schemas/package.json +++ b/schemas/package.json @@ -1,6 +1,6 @@ { "name": "godoxy-schemas", - "version": "0.10.0-3", + "version": "0.10.1-6", "description": "JSON Schema and typescript types for GoDoxy configuration", "license": "MIT", "repository": { @@ -8,9 +8,11 @@ "url": "https://github.com/yusing/godoxy" }, "files": [ - "schemas/", - "README.md", - "LICENSE" + "**/*.ts", + "**/*.js", + "*.schema.json", + "../README.md", + "../LICENSE" ], "type": "module", "main": "./index.ts", @@ -22,15 +24,14 @@ } }, "devDependencies": { - "prettier": "^3.4.2", - "typescript": "^5.7.3", + "prettier": "^3.5.3", + "typescript": "^5.8.3", "typescript-json-schema": "^0.65.1" }, "displayName": "GoDoxy Types", - "packageManager": "bun@1.2.0", + "packageManager": "bun@1.2.9", "publisher": "yusing", "scripts": { - "gen-schema": "make gen-schema", - "format:write": "prettier --write \"schemas/**/*.ts\" --cache" + "format:write": "prettier --write \"**/*.ts\" --cache" } } \ No newline at end of file diff --git a/schemas/providers/healthcheck.d.ts b/schemas/providers/healthcheck.d.ts index c819e54..05b6df5 100644 --- a/schemas/providers/healthcheck.d.ts +++ b/schemas/providers/healthcheck.d.ts @@ -3,30 +3,30 @@ import { Duration, URI } from "../types"; * @additionalProperties false */ export type HealthcheckConfig = { - /** Disable healthcheck - * - * @default false - */ - disable?: boolean; - /** Healthcheck path - * - * @default / - */ - path?: URI; - /** - * Use GET instead of HEAD - * - * @default false - */ - use_get?: boolean; - /** Healthcheck interval - * - * @default 5s - */ - interval?: Duration; - /** Healthcheck timeout - * - * @default 5s - */ - timeout?: Duration; + /** Disable healthcheck + * + * @default false + */ + disable?: boolean; + /** Healthcheck path + * + * @default / + */ + path?: URI; + /** + * Use GET instead of HEAD + * + * @default false + */ + use_get?: boolean; + /** Healthcheck interval + * + * @default 5s + */ + interval?: Duration; + /** Healthcheck timeout + * + * @default 5s + */ + timeout?: Duration; }; diff --git a/schemas/providers/homepage.d.ts b/schemas/providers/homepage.d.ts index db64be9..a51a129 100644 --- a/schemas/providers/homepage.d.ts +++ b/schemas/providers/homepage.d.ts @@ -3,19 +3,19 @@ import { URL } from "../types"; * @additionalProperties false */ export type HomepageConfig = { - /** Whether show in dashboard - * - * @default true - */ - show?: boolean; - name?: string; - icon?: URL | WalkxcodeIcon | ExternalIcon | TargetRelativeIconPath; - description?: string; - url?: URL; - category?: string; - widget_config?: { - [key: string]: any; - }; + /** Whether show in dashboard + * + * @default true + */ + show?: boolean; + name?: string; + icon?: URL | WalkxcodeIcon | ExternalIcon | TargetRelativeIconPath; + description?: string; + url?: URL; + category?: string; + widget_config?: { + [key: string]: any; + }; }; /** Walkxcode icon * diff --git a/schemas/providers/idlewatcher.d.ts b/schemas/providers/idlewatcher.d.ts index d9aed44..ed5daf5 100644 --- a/schemas/providers/idlewatcher.d.ts +++ b/schemas/providers/idlewatcher.d.ts @@ -1,25 +1,35 @@ import { Duration, URI } from "../types"; export declare const STOP_METHODS: readonly ["pause", "stop", "kill"]; export type StopMethod = (typeof STOP_METHODS)[number]; -export declare const STOP_SIGNALS: readonly ["", "SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT", "INT", "TERM", "HUP", "QUIT"]; +export declare const STOP_SIGNALS: readonly [ + "", + "SIGINT", + "SIGTERM", + "SIGHUP", + "SIGQUIT", + "INT", + "TERM", + "HUP", + "QUIT", +]; export type Signal = (typeof STOP_SIGNALS)[number]; export type IdleWatcherConfig = { - idle_timeout?: Duration; - /** Wake timeout - * - * @default 30s - */ - wake_timeout?: Duration; - /** Stop timeout - * - * @default 30s - */ - stop_timeout?: Duration; - /** Stop method - * - * @default stop - */ - stop_method?: StopMethod; - stop_signal?: Signal; - start_endpoint?: URI; + idle_timeout?: Duration; + /** Wake timeout + * + * @default 30s + */ + wake_timeout?: Duration; + /** Stop timeout + * + * @default 30s + */ + stop_timeout?: Duration; + /** Stop method + * + * @default stop + */ + stop_method?: StopMethod; + stop_signal?: Signal; + start_endpoint?: URI; }; diff --git a/schemas/providers/loadbalance.d.ts b/schemas/providers/loadbalance.d.ts index 8ea4243..c2ccdcd 100644 --- a/schemas/providers/loadbalance.d.ts +++ b/schemas/providers/loadbalance.d.ts @@ -1,28 +1,38 @@ import { RealIP } from "../middlewares/middlewares"; -export declare const LOAD_BALANCE_MODES: readonly ["round_robin", "least_conn", "ip_hash"]; +export declare const LOAD_BALANCE_MODES: readonly [ + "round_robin", + "least_conn", + "ip_hash", +]; export type LoadBalanceMode = (typeof LOAD_BALANCE_MODES)[number]; export type LoadBalanceConfigBase = { - /** Alias (subdomain or FDN) of load-balancer - * - * @minLength 1 - */ - link: string; - /** Load-balance weight (reserved for future use) - * - * @minimum 0 - * @maximum 100 - */ - weight?: number; + /** Alias (subdomain or FDN) of load-balancer + * + * @minLength 1 + */ + link: string; + /** Load-balance weight (reserved for future use) + * + * @minimum 0 + * @maximum 100 + */ + weight?: number; }; -export type LoadBalanceConfig = LoadBalanceConfigBase & ({} | RoundRobinLoadBalanceConfig | LeastConnLoadBalanceConfig | IPHashLoadBalanceConfig); +export type LoadBalanceConfig = LoadBalanceConfigBase & + ( + | {} + | RoundRobinLoadBalanceConfig + | LeastConnLoadBalanceConfig + | IPHashLoadBalanceConfig + ); export type IPHashLoadBalanceConfig = { - mode: "ip_hash"; - /** Real IP config, header to get client IP from */ - config: RealIP; + mode: "ip_hash"; + /** Real IP config, header to get client IP from */ + config: RealIP; }; export type LeastConnLoadBalanceConfig = { - mode: "least_conn"; + mode: "least_conn"; }; export type RoundRobinLoadBalanceConfig = { - mode: "round_robin"; + mode: "round_robin"; }; diff --git a/schemas/providers/routes.d.ts b/schemas/providers/routes.d.ts index 1a5564b..4aaed50 100644 --- a/schemas/providers/routes.d.ts +++ b/schemas/providers/routes.d.ts @@ -1,7 +1,15 @@ import { AccessLogConfig } from "../config/access_log"; import { accessLogExamples } from "../config/entrypoint"; import { MiddlewaresMap } from "../middlewares/middlewares"; -import { Duration, Hostname, IPv4, IPv6, PathPattern, Port, StreamPort } from "../types"; +import { + Duration, + Hostname, + IPv4, + IPv6, + PathPattern, + Port, + StreamPort, +} from "../types"; import { HealthcheckConfig } from "./healthcheck"; import { HomepageConfig } from "./homepage"; import { LoadBalanceConfig } from "./loadbalance"; @@ -11,122 +19,130 @@ export type ProxyScheme = (typeof PROXY_SCHEMES)[number]; export type StreamScheme = (typeof STREAM_SCHEMES)[number]; export type Route = ReverseProxyRoute | FileServerRoute | StreamRoute; export type Routes = { - [key: string]: Route; + [key: string]: Route; }; export type ReverseProxyRoute = { - /** Alias (subdomain or FDN) - * @minLength 1 - */ - alias?: string; - /** Proxy scheme - * - * @default http - */ - scheme?: ProxyScheme; - /** Proxy host - * - * @default localhost - */ - host?: Hostname | IPv4 | IPv6; - /** Proxy port - * - * @default 80 - */ - port?: Port; - /** Skip TLS verification - * - * @default false - */ - no_tls_verify?: boolean; - /** Response header timeout - * - * @default 60s - */ - response_header_timeout?: Duration; - /** Path patterns (only patterns that match will be proxied). - * - * See https://pkg.go.dev/net/http#hdr-Patterns-ServeMux - */ - path_patterns?: PathPattern[]; - /** Healthcheck config */ - healthcheck?: HealthcheckConfig; - /** Load balance config */ - load_balance?: LoadBalanceConfig; - /** Middlewares */ - middlewares?: MiddlewaresMap; - /** Homepage config - * - * @examples require(".").homepageExamples - */ - homepage?: HomepageConfig; - /** Access log config - * - * @examples require(".").accessLogExamples - */ - access_log?: AccessLogConfig; + /** Alias (subdomain or FDN) + * @minLength 1 + */ + alias?: string; + /** Proxy scheme + * + * @default http + */ + scheme?: ProxyScheme; + /** Proxy host + * + * @default localhost + */ + host?: Hostname | IPv4 | IPv6; + /** Proxy port + * + * @default 80 + */ + port?: Port; + /** Skip TLS verification + * + * @default false + */ + no_tls_verify?: boolean; + /** Response header timeout + * + * @default 60s + */ + response_header_timeout?: Duration; + /** Path patterns (only patterns that match will be proxied). + * + * See https://pkg.go.dev/net/http#hdr-Patterns-ServeMux + */ + path_patterns?: PathPattern[]; + /** Healthcheck config */ + healthcheck?: HealthcheckConfig; + /** Load balance config */ + load_balance?: LoadBalanceConfig; + /** Middlewares */ + middlewares?: MiddlewaresMap; + /** Homepage config + * + * @examples require(".").homepageExamples + */ + homepage?: HomepageConfig; + /** Access log config + * + * @examples require(".").accessLogExamples + */ + access_log?: AccessLogConfig; }; export type FileServerRoute = { - /** Alias (subdomain or FDN) - * @minLength 1 - */ - alias?: string; - scheme: "fileserver"; - root: string; - /** Path patterns (only patterns that match will be proxied). - * - * See https://pkg.go.dev/net/http#hdr-Patterns-ServeMux - */ - path_patterns?: PathPattern[]; - /** Middlewares */ - middlewares?: MiddlewaresMap; - /** Homepage config - * - * @examples require(".").homepageExamples - */ - homepage?: HomepageConfig; - /** Access log config - * - * @examples require(".").accessLogExamples - */ - access_log?: AccessLogConfig; + /** Alias (subdomain or FDN) + * @minLength 1 + */ + alias?: string; + scheme: "fileserver"; + root: string; + /** Path patterns (only patterns that match will be proxied). + * + * See https://pkg.go.dev/net/http#hdr-Patterns-ServeMux + */ + path_patterns?: PathPattern[]; + /** Middlewares */ + middlewares?: MiddlewaresMap; + /** Homepage config + * + * @examples require(".").homepageExamples + */ + homepage?: HomepageConfig; + /** Access log config + * + * @examples require(".").accessLogExamples + */ + access_log?: AccessLogConfig; + /** Healthcheck config */ + healthcheck?: HealthcheckConfig; }; export type StreamRoute = { - /** Alias (subdomain or FDN) - * @minLength 1 - */ - alias?: string; - /** Stream scheme - * - * @default tcp - */ - scheme?: StreamScheme; - /** Stream host - * - * @default localhost - */ - host?: Hostname | IPv4 | IPv6; - port: StreamPort; - /** Healthcheck config */ - healthcheck?: HealthcheckConfig; + /** Alias (subdomain or FDN) + * @minLength 1 + */ + alias?: string; + /** Stream scheme + * + * @default tcp + */ + scheme?: StreamScheme; + /** Stream host + * + * @default localhost + */ + host?: Hostname | IPv4 | IPv6; + port: StreamPort; + /** Healthcheck config */ + healthcheck?: HealthcheckConfig; }; -export declare const homepageExamples: ({ - name: string; - icon: string; - category: string; -} | { - name: string; - icon: string; - category?: undefined; -})[]; -export declare const loadBalanceExamples: ({ - link: string; - mode: string; - config?: undefined; -} | { - link: string; - mode: string; - config: { +export declare const homepageExamples: ( + | { + name: string; + icon: string; + category: string; + } + | { + name: string; + icon: string; + category?: undefined; + } +)[]; +export declare const loadBalanceExamples: ( + | { + link: string; + mode: string; + config?: undefined; + } + | { + link: string; + mode: string; + config: { header: string; - }; -})[]; + }; + } +)[]; export { accessLogExamples }; diff --git a/schemas/providers/routes.ts b/schemas/providers/routes.ts index 86d4375..29ab6d8 100644 --- a/schemas/providers/routes.ts +++ b/schemas/providers/routes.ts @@ -1,7 +1,15 @@ import { AccessLogConfig } from "../config/access_log"; import { accessLogExamples } from "../config/entrypoint"; import { MiddlewaresMap } from "../middlewares/middlewares"; -import { Duration, Hostname, IPv4, IPv6, PathPattern, Port, StreamPort } from "../types"; +import { + Duration, + Hostname, + IPv4, + IPv6, + PathPattern, + Port, + StreamPort, +} from "../types"; import { HealthcheckConfig } from "./healthcheck"; import { HomepageConfig } from "./homepage"; import { LoadBalanceConfig } from "./loadbalance"; @@ -94,7 +102,9 @@ export type FileServerRoute = { * @examples require(".").accessLogExamples */ access_log?: AccessLogConfig; -} + /** Healthcheck config */ + healthcheck?: HealthcheckConfig; +}; export type StreamRoute = { /** Alias (subdomain or FDN) diff --git a/schemas/routes.schema.json b/schemas/routes.schema.json index 25a59bb..5c2be97 100644 --- a/schemas/routes.schema.json +++ b/schemas/routes.schema.json @@ -1 +1 @@ -{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":{"$ref":"#/definitions/Route"},"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"}]},"Duration":{"pattern":"^([0-9]+(ms|s|m|h))+$","type":"string"},"HTTPHeader":{"description":"HTTP Header","pattern":"^[a-zA-Z0-9\\-]+$","type":"string"},"LoadBalanceConfig":{"anyOf":[{"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"},"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":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"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":{"CIDRWhitelist":{"$ref":"#/definitions/Omit"},"CloudflareRealIP":{"$ref":"#/definitions/Omit"},"CustomErrorPage":{"$ref":"#/definitions/Omit"},"ErrorPage":{"$ref":"#/definitions/Omit"},"HideXForwarded":{"$ref":"#/definitions/Omit"},"ModifyRequest":{"$ref":"#/definitions/Omit"},"ModifyResponse":{"$ref":"#/definitions/Omit"},"OIDC":{"$ref":"#/definitions/Omit"},"RateLimit":{"$ref":"#/definitions/Omit"},"RealIP":{"$ref":"#/definitions/Omit"},"RedirectHTTP":{"$ref":"#/definitions/Omit"},"Request":{"$ref":"#/definitions/Omit"},"Response":{"$ref":"#/definitions/Omit"},"SetXForwarded":{"$ref":"#/definitions/Omit"},"cidrWhitelist":{"$ref":"#/definitions/Omit"},"cidr_whitelist":{"$ref":"#/definitions/Omit"},"cloudflareRealIp":{"$ref":"#/definitions/Omit"},"cloudflare_real_ip":{"$ref":"#/definitions/Omit"},"customErrorPage":{"$ref":"#/definitions/Omit"},"custom_error_page":{"$ref":"#/definitions/Omit"},"errorPage":{"$ref":"#/definitions/Omit"},"error_page":{"$ref":"#/definitions/Omit"},"hideXForwarded":{"$ref":"#/definitions/Omit"},"hide_x_forwarded":{"$ref":"#/definitions/Omit"},"modifyRequest":{"$ref":"#/definitions/Omit"},"modifyResponse":{"$ref":"#/definitions/Omit"},"modify_request":{"$ref":"#/definitions/Omit"},"modify_response":{"$ref":"#/definitions/Omit"},"oidc":{"$ref":"#/definitions/Omit"},"rateLimit":{"$ref":"#/definitions/Omit"},"rate_limit":{"$ref":"#/definitions/Omit"},"realIP":{"$ref":"#/definitions/Omit"},"real_ip":{"$ref":"#/definitions/Omit"},"redirectHTTP":{"$ref":"#/definitions/Omit"},"redirect_http":{"$ref":"#/definitions/Omit"},"request":{"$ref":"#/definitions/Omit"},"response":{"$ref":"#/definitions/Omit"},"setXForwarded":{"$ref":"#/definitions/Omit"},"set_x_forwarded":{"$ref":"#/definitions/Omit"}},"type":"object"},{"type":"object"}]},"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":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"add_prefix":{"description":"Add prefix to request URL","type":"string"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"}},"type":"object"},"Omit":{"additionalProperties":false,"properties":{"add_headers":{"additionalProperties":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"}},"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":{"$ref":"#/definitions/Duration","default":"1s","description":"Duration of the rate limit"}},"required":["average","burst"],"type":"object"},"Omit":{"additionalProperties":false,"properties":{"from":{"items":{"$ref":"#/definitions/CIDR"},"type":"array"},"header":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"recursive":{"default":false,"description":"Recursive resolve the IP","type":"boolean"}},"required":["from"],"type":"object"},"Omit":{"additionalProperties":false,"properties":{"bypass":{"additionalProperties":false,"description":"Bypass redirect","properties":{"user_agents":{"description":"Bypass redirect for user agents","items":{"type":"string"},"type":"array"}},"type":"object"}},"type":"object"},"Omit":{"additionalProperties":false,"type":"object"},"PathPattern":{"pattern":"^(?:([A-Z]+) )?(?:([a-zA-Z0-9.-]+)\\\\/)?(\\\\/[^\\\\s]*)$","type":"string"},"Port":{"maximum":65535,"minimum":0,"type":"integer"},"ProxyScheme":{"enum":["http","https"],"type":"string"},"Route":{"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":{"$ref":"#/definitions/HTTPHeader"},"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":{"$ref":"#/definitions/URI"}},"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"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":{"anyOf":[{"format":"uri","type":"string"},{"description":"Walkxcode icon","pattern":"^(png|svg|webp)\\/[\\w\\d\\-_]+\\.\\1","type":"string"},{"pattern":"^@selfhst/.*\\..*$","type":"string"},{"pattern":"^@walkxcode/.*\\..*$","type":"string"},{"pattern":"^@target/.*$","type":"string"},{"pattern":"^/.*$","type":"string"}]},"name":{"type":"string"},"show":{"default":true,"description":"Whether show in dashboard","type":"boolean"},"url":{"$ref":"#/definitions/URL"},"widget_config":{"additionalProperties":{},"type":"object"}},"type":"object"},"host":{"anyOf":[{"format":"hostname","type":"string"},{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}],"default":"localhost","description":"Proxy host"},"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":{"$ref":"#/definitions/PathPattern"},"type":"array"},"port":{"$ref":"#/definitions/Port","default":80,"description":"Proxy port"},"response_header_timeout":{"$ref":"#/definitions/Duration","default":"60s","description":"Response header timeout"},"scheme":{"$ref":"#/definitions/ProxyScheme","default":"http","description":"Proxy scheme"}},"type":"object"},{"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":{"$ref":"#/definitions/HTTPHeader"},"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":{"$ref":"#/definitions/URI"}},"required":["path"],"type":"object"},"alias":{"description":"Alias (subdomain or FDN)","minLength":1,"type":"string"},"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":{"anyOf":[{"format":"uri","type":"string"},{"description":"Walkxcode icon","pattern":"^(png|svg|webp)\\/[\\w\\d\\-_]+\\.\\1","type":"string"},{"pattern":"^@selfhst/.*\\..*$","type":"string"},{"pattern":"^@walkxcode/.*\\..*$","type":"string"},{"pattern":"^@target/.*$","type":"string"},{"pattern":"^/.*$","type":"string"}]},"name":{"type":"string"},"show":{"default":true,"description":"Whether show in dashboard","type":"boolean"},"url":{"$ref":"#/definitions/URL"},"widget_config":{"additionalProperties":{},"type":"object"}},"type":"object"},"middlewares":{"$ref":"#/definitions/MiddlewaresMap","description":"Middlewares"},"path_patterns":{"description":"Path patterns (only patterns that match will be proxied).\n\nSee https://pkg.go.dev/net/http#hdr-Patterns-ServeMux","items":{"$ref":"#/definitions/PathPattern"},"type":"array"},"root":{"type":"string"},"scheme":{"const":"fileserver","type":"string"}},"required":["root","scheme"],"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"use_get":{"default":false,"description":"Use GET instead of HEAD","type":"boolean"}},"type":"object"},"host":{"anyOf":[{"format":"hostname","type":"string"},{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}],"default":"localhost","description":"Stream host"},"port":{"$ref":"#/definitions/StreamPort"},"scheme":{"$ref":"#/definitions/StreamScheme","default":"tcp","description":"Stream scheme"}},"required":["port"],"type":"object"}]},"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"}]},"StreamPort":{"pattern":"^\\d+:\\d+$","type":"string"},"StreamScheme":{"enum":["tcp","udp"],"type":"string"},"URI":{"format":"uri-reference","type":"string"},"URL":{"format":"uri","type":"string"}},"type":"object"} \ No newline at end of file +{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":{"$ref":"#/definitions/Route"},"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"}]},"Duration":{"pattern":"^([0-9]+(ms|s|m|h))+$","type":"string"},"HTTPHeader":{"description":"HTTP Header","pattern":"^[a-zA-Z0-9\\-]+$","type":"string"},"LoadBalanceConfig":{"anyOf":[{"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"},"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":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"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":{"CIDRWhitelist":{"$ref":"#/definitions/Omit"},"CloudflareRealIP":{"$ref":"#/definitions/Omit"},"CustomErrorPage":{"$ref":"#/definitions/Omit"},"ErrorPage":{"$ref":"#/definitions/Omit"},"HideXForwarded":{"$ref":"#/definitions/Omit"},"ModifyRequest":{"$ref":"#/definitions/Omit"},"ModifyResponse":{"$ref":"#/definitions/Omit"},"OIDC":{"$ref":"#/definitions/Omit"},"RateLimit":{"$ref":"#/definitions/Omit"},"RealIP":{"$ref":"#/definitions/Omit"},"RedirectHTTP":{"$ref":"#/definitions/Omit"},"Request":{"$ref":"#/definitions/Omit"},"Response":{"$ref":"#/definitions/Omit"},"SetXForwarded":{"$ref":"#/definitions/Omit"},"cidrWhitelist":{"$ref":"#/definitions/Omit"},"cidr_whitelist":{"$ref":"#/definitions/Omit"},"cloudflareRealIp":{"$ref":"#/definitions/Omit"},"cloudflare_real_ip":{"$ref":"#/definitions/Omit"},"customErrorPage":{"$ref":"#/definitions/Omit"},"custom_error_page":{"$ref":"#/definitions/Omit"},"errorPage":{"$ref":"#/definitions/Omit"},"error_page":{"$ref":"#/definitions/Omit"},"hideXForwarded":{"$ref":"#/definitions/Omit"},"hide_x_forwarded":{"$ref":"#/definitions/Omit"},"modifyRequest":{"$ref":"#/definitions/Omit"},"modifyResponse":{"$ref":"#/definitions/Omit"},"modify_request":{"$ref":"#/definitions/Omit"},"modify_response":{"$ref":"#/definitions/Omit"},"oidc":{"$ref":"#/definitions/Omit"},"rateLimit":{"$ref":"#/definitions/Omit"},"rate_limit":{"$ref":"#/definitions/Omit"},"realIP":{"$ref":"#/definitions/Omit"},"real_ip":{"$ref":"#/definitions/Omit"},"redirectHTTP":{"$ref":"#/definitions/Omit"},"redirect_http":{"$ref":"#/definitions/Omit"},"request":{"$ref":"#/definitions/Omit"},"response":{"$ref":"#/definitions/Omit"},"setXForwarded":{"$ref":"#/definitions/Omit"},"set_x_forwarded":{"$ref":"#/definitions/Omit"}},"type":"object"},{"type":"object"}]},"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":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"add_prefix":{"description":"Add prefix to request URL","type":"string"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"}},"type":"object"},"Omit":{"additionalProperties":false,"properties":{"add_headers":{"additionalProperties":false,"description":"Add HTTP headers","items":{"type":"string"},"type":"array"},"hide_headers":{"description":"Hide HTTP headers","items":{"$ref":"#/definitions/HTTPHeader"},"type":"array"},"set_headers":{"additionalProperties":false,"description":"Set HTTP headers","items":{"type":"string"},"type":"array"}},"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":{"$ref":"#/definitions/Duration","default":"1s","description":"Duration of the rate limit"}},"required":["average","burst"],"type":"object"},"Omit":{"additionalProperties":false,"properties":{"from":{"items":{"$ref":"#/definitions/CIDR"},"type":"array"},"header":{"$ref":"#/definitions/HTTPHeader","default":"X-Real-IP","description":"Header to get the client IP from"},"recursive":{"default":false,"description":"Recursive resolve the IP","type":"boolean"}},"required":["from"],"type":"object"},"Omit":{"additionalProperties":false,"properties":{"bypass":{"additionalProperties":false,"description":"Bypass redirect","properties":{"user_agents":{"description":"Bypass redirect for user agents","items":{"type":"string"},"type":"array"}},"type":"object"}},"type":"object"},"Omit":{"additionalProperties":false,"type":"object"},"PathPattern":{"pattern":"^(?:([A-Z]+) )?(?:([a-zA-Z0-9.-]+)\\\\/)?(\\\\/[^\\\\s]*)$","type":"string"},"Port":{"maximum":65535,"minimum":0,"type":"integer"},"ProxyScheme":{"enum":["http","https"],"type":"string"},"Route":{"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":{"$ref":"#/definitions/HTTPHeader"},"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":{"$ref":"#/definitions/URI"}},"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"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":{"anyOf":[{"format":"uri","type":"string"},{"description":"Walkxcode icon","pattern":"^(png|svg|webp)\\/[\\w\\d\\-_]+\\.\\1","type":"string"},{"pattern":"^@selfhst/.*\\..*$","type":"string"},{"pattern":"^@walkxcode/.*\\..*$","type":"string"},{"pattern":"^@target/.*$","type":"string"},{"pattern":"^/.*$","type":"string"}]},"name":{"type":"string"},"show":{"default":true,"description":"Whether show in dashboard","type":"boolean"},"url":{"$ref":"#/definitions/URL"},"widget_config":{"additionalProperties":{},"type":"object"}},"type":"object"},"host":{"anyOf":[{"format":"hostname","type":"string"},{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}],"default":"localhost","description":"Proxy host"},"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":{"$ref":"#/definitions/PathPattern"},"type":"array"},"port":{"$ref":"#/definitions/Port","default":80,"description":"Proxy port"},"response_header_timeout":{"$ref":"#/definitions/Duration","default":"60s","description":"Response header timeout"},"scheme":{"$ref":"#/definitions/ProxyScheme","default":"http","description":"Proxy scheme"}},"type":"object"},{"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":{"$ref":"#/definitions/HTTPHeader"},"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":{"$ref":"#/definitions/URI"}},"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"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":{"anyOf":[{"format":"uri","type":"string"},{"description":"Walkxcode icon","pattern":"^(png|svg|webp)\\/[\\w\\d\\-_]+\\.\\1","type":"string"},{"pattern":"^@selfhst/.*\\..*$","type":"string"},{"pattern":"^@walkxcode/.*\\..*$","type":"string"},{"pattern":"^@target/.*$","type":"string"},{"pattern":"^/.*$","type":"string"}]},"name":{"type":"string"},"show":{"default":true,"description":"Whether show in dashboard","type":"boolean"},"url":{"$ref":"#/definitions/URL"},"widget_config":{"additionalProperties":{},"type":"object"}},"type":"object"},"middlewares":{"$ref":"#/definitions/MiddlewaresMap","description":"Middlewares"},"path_patterns":{"description":"Path patterns (only patterns that match will be proxied).\n\nSee https://pkg.go.dev/net/http#hdr-Patterns-ServeMux","items":{"$ref":"#/definitions/PathPattern"},"type":"array"},"root":{"type":"string"},"scheme":{"const":"fileserver","type":"string"}},"required":["root","scheme"],"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":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck interval"},"path":{"$ref":"#/definitions/URI","default":"/","description":"Healthcheck path"},"timeout":{"$ref":"#/definitions/Duration","default":"5s","description":"Healthcheck timeout"},"use_get":{"default":false,"description":"Use GET instead of HEAD","type":"boolean"}},"type":"object"},"host":{"anyOf":[{"format":"hostname","type":"string"},{"format":"ipv4","type":"string"},{"format":"ipv6","type":"string"}],"default":"localhost","description":"Stream host"},"port":{"$ref":"#/definitions/StreamPort"},"scheme":{"$ref":"#/definitions/StreamScheme","default":"tcp","description":"Stream scheme"}},"required":["port"],"type":"object"}]},"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"}]},"StreamPort":{"pattern":"^\\d+:\\d+$","type":"string"},"StreamScheme":{"enum":["tcp","udp"],"type":"string"},"URI":{"format":"uri-reference","type":"string"},"URL":{"format":"uri","type":"string"}},"type":"object"} \ No newline at end of file diff --git a/schemas/tsconfig.json b/schemas/tsconfig.json index 3a87871..5ac8e5d 100644 --- a/schemas/tsconfig.json +++ b/schemas/tsconfig.json @@ -5,12 +5,14 @@ "target": "ESNext", "module": "ESNext", "moduleResolution": "Node", - "strict": true, - "esModuleInterop": true, + "strict": false, + "esModuleInterop": false, "forceConsistentCasingInFileNames": true, - "allowJs": true, + "allowJs": false, "resolveJsonModule": true, - "declaration": true + "declaration": true, + "allowSyntheticDefaultImports": true }, - "include": ["."] + "include": ["**/*.ts"], + "exclude": ["node_modules"] } diff --git a/schemas/types.d.ts b/schemas/types.d.ts index 1031c77..f5390ae 100644 --- a/schemas/types.d.ts +++ b/schemas/types.d.ts @@ -4,7 +4,17 @@ export type Null = null; export type Nullable = T | Null; export type NullOrEmptyMap = {} | Null; -export declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "CONNECT", "HEAD", "OPTIONS", "TRACE"]; +export declare const HTTP_METHODS: readonly [ + "GET", + "POST", + "PUT", + "PATCH", + "DELETE", + "CONNECT", + "HEAD", + "OPTIONS", + "TRACE", +]; export type HTTPMethod = (typeof HTTP_METHODS)[number]; /** * HTTP Header @@ -49,7 +59,13 @@ export type IPv4 = string & {}; * @type string */ export type IPv6 = string & {}; -export type CIDR = `${number}.${number}.${number}.${number}` | `${string}:${string}:${string}:${string}:${string}:${string}:${string}:${string}` | `${number}.${number}.${number}.${number}/${number}` | `::${number}` | `${string}::/${number}` | `${string}:${string}::/${number}`; +export type CIDR = + | `${number}.${number}.${number}.${number}` + | `${string}:${string}:${string}:${string}:${string}:${string}:${string}:${string}` + | `${number}.${number}.${number}.${number}/${number}` + | `::${number}` + | `${string}::/${number}` + | `${string}:${string}::/${number}`; /** * @type integer * @minimum 0