Files
ProxMenux/AppImage/lib/lxc-app-editor-errors.ts
T

131 lines
9.0 KiB
TypeScript

type Translate = (key: string, params?: Record<string, string | number>) => string
// Exact lxc_apps validation/persistence messages; never change their API contract.
// Anchored patterns leave unknown diagnostics intact, including paths and commands.
const RULES: [RegExp, string, string[]][] = [
[/^an OCI operation on this container is running$/, "ociBusy", []],
[/^([\s\S]+) is not installed via dpkg$/, "dpkgMissing", ["package"]],
[/^dpkg\-query failed$/, "dpkgFailed", []],
[/^no version matched in dpkg output$/, "dpkgNoVersion", []],
[/^apk info failed$/, "apkFailed", []],
[/^no version matched in apk output$/, "apkNoVersion", []],
[/^could not read ([\s\S]+)$/, "fileRead", ["path"]],
[/^file_regex did not match ([\s\S]+)$/, "fileNoMatch", ["path"]],
[/^binary invocation failed$/, "binaryFailed", []],
[/^no version matched in binary output$/, "binaryNoVersion", []],
[/^python \-c importlib\.metadata failed$/, "pythonFailed", []],
[/^no version matched in Python distribution output$/, "pythonNoVersion", []],
[/^could not resolve the container's installed image$/, "dockerImageResolve", []],
[/^docker inspect failed$/, "dockerInspectFailed", []],
[/^container has no ([\s\S]+) label$/, "dockerLabelMissing", ["label"]],
[/^docker label reports ([\s\S]+) \(mutable tag, not a version\)$/, "dockerLabelMutable", ["tag"]],
[/^no version matched in docker label output$/, "dockerLabelNoVersion", []],
[/^docker exec failed$/, "dockerExecFailed", []],
[/^no version matched in docker exec output$/, "dockerExecNoVersion", []],
[/^command_argv is empty$/, "commandEmpty", []],
[/^command failed$/, "commandFailed", []],
[/^no version matched in command output$/, "commandNoVersion", []],
[/^unsupported method: ([\s\S]+)$/, "unsupportedMethod", ["method"]],
[/^unknown upstream_type: ([\s\S]+)$/, "unknownUpstream", ["type"]],
[/^([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+): not found$/, "githubNotFound", ["repo"]],
[/^github rejected the request \(403\)$/, "githubRejected", []],
[/^github error (\d+)$/, "githubError", ["code"]],
[/^no tag \/ release name in response$/, "noRelease", []],
[/^tag_regex did not match '([\s\S]+)'$/, "tagNoMatch", ["tag"]],
[/^http error (\d+)$/, "httpError", ["code"]],
[/^invalid JSON response: ([\s\S]+)$/, "invalidJson", ["detail"]],
[/^json_path '([\s\S]+)' did not resolve$/, "jsonPathUnresolved", ["path"]],
[/^empty value at json_path$/, "jsonEmpty", []],
[/^no tags matched \(docker_hub\)$/, "dockerNoTags", []],
[/^tag_regex matched only moving tags; use Docker image digest tracking$/, "dockerMovingOnly", []],
[/^docker hub error (\d+)$/, "dockerHubError", ["code"]],
[/^invalid docker hub JSON: ([\s\S]+)$/, "dockerHubJson", ["detail"]],
[/^no tags returned by docker hub$/, "dockerHubEmpty", []],
[/^payload must be a JSON object$/, "payload", []],
[/^name is required and must be 1\-64 chars of letters\/digits\/spaces\/\._\+\-\(\)\/$/, "name", []],
[/^installed_via must be one of: ([\s\S]+) or empty$/, "method", ["values"]],
[/^package is required \(letters\/digits\/\._\+@:\/ up to 127 chars\)$/, "package", []],
[/^file_path is required and must be an absolute path$/, "filePath", []],
[/^file_regex is required$/, "fileRegex", []],
[/^file_regex is not a valid regex: ([\s\S]+)$/, "fileRegexInvalid", ["detail"]],
[/^binary_path is required and must be an absolute path$/, "binaryPath", []],
[/^python_path is required and must be an absolute path$/, "pythonPath", []],
[/^distribution is required \(PEP 503 name\)$/, "distribution", []],
[/^container_name is required \(docker naming rules\)$/, "container", []],
[/^label is required \(OCI label naming rules\)$/, "label", []],
[/^binary_path is required \(absolute path or bare command\)$/, "dockerBinary", []],
[/^installed_version is required for the manual method$/, "manualVersion", []],
[/^installed_version exceeds (\d+) chars$/, "versionLength", ["max"]],
[/^installed_version contains a forbidden control character$/, "versionControl", []],
[/^installed_regex is not a valid regex: ([\s\S]+)$/, "installedRegexInvalid", ["detail"]],
[/^upstream_type must be one of: ([\s\S]+)$/, "upstreamType", ["values"]],
[/^tag_regex is not a valid regex: ([\s\S]+)$/, "tagRegexInvalid", ["detail"]],
[/^repo is required for upstream_type=github$/, "repoRequired", []],
[/^repo must be 'owner\/name'$/, "repoFormat", []],
[/^github_source must be one of: ([\s\S]+)$/, "githubSource", ["values"]],
[/^upstream_url is required for upstream_type=http_json$/, "upstreamUrlRequired", []],
[/^upstream_url must be an http\(s\) URL$/, "upstreamUrl", []],
[/^upstream_url exceeds (\d+) chars$/, "upstreamUrlLength", ["max"]],
[/^upstream_json_path is required for upstream_type=http_json$/, "jsonPathRequired", []],
[/^upstream_json_path exceeds (\d+) chars$/, "jsonPathLength", ["max"]],
[/^upstream_json_path uses forbidden characters$/, "jsonPathCharacters", []],
[/^docker_image is required for upstream_type=docker_hub$/, "dockerImageRequired", []],
[/^docker_image exceeds (\d+) chars$/, "dockerImageLength", ["max"]],
[/^docker_image must match Docker Hub naming \(owner\/name or name\)$/, "dockerImageFormat", []],
[/^health_path must be a valid URL path \(max 255 chars\)$/, "healthPath", []],
[/^logo_url must be an http\(s\) URL or this VM's cached local icon$/, "logoUrl", []],
[/^invalid discovery_id$/, "discoveryId", []],
[/^helper_slug must be a lowercase slug \(letters\/digits\/\._\-\)$/, "helperSlug", []],
[/^update_via only accepts 'docker'$/, "updateVia", []],
[/^update_via=docker requires a docker_label or docker_exec detector$/, "dockerDetector", []],
[/^update_via=docker cannot be combined with ([\s\S]+)$/, "dockerConflict", ["field"]],
[/^update_command must be a string$/, "updateCommandType", []],
[/^update_command exceeds (\d+) chars$/, "updateCommandLength", ["max"]],
[/^update_command contains a null byte$/, "updateCommandNull", []],
[/^update_method must be none, helper or custom$/, "updateMethod", []],
[/^update_command is required for update_method=custom$/, "updateCommandRequired", []],
[/^update_command is only allowed for update_method=custom$/, "updateCommandOnlyCustom", []],
[/^a supported helper_slug is required for update_method=helper$/, "helperRequired", []],
[/^Docker\-delegated apps update through their image, not a separate app updater$/, "dockerUpdater", []],
[/^command_argv is required \(non\-empty list\)$/, "commandRequired", []],
[/^command_argv must be a non\-empty list of strings$/, "commandList", []],
[/^command_argv accepts at most (\d+) entries$/, "commandCount", ["max"]],
[/^command_argv\[(\d+)\] must be a non\-empty string$/, "commandEntry", ["index"]],
[/^command_argv\[(\d+)\] exceeds (\d+) chars$/, "commandEntryLength", ["index", "max"]],
[/^command_argv\[(\d+)\] contains a forbidden control character$/, "commandEntryControl", ["index"]],
[/^binary_args must be a list of strings$/, "binaryArgsList", []],
[/^binary_args accepts at most (\d+) entries$/, "binaryArgsCount", ["max"]],
[/^binary_args\[(\d+)\] must be a non\-empty string$/, "binaryArgEntry", ["index"]],
[/^binary_args\[(\d+)\] exceeds (\d+) chars$/, "binaryArgLength", ["index", "max"]],
[/^binary_args\[(\d+)\] contains a forbidden control character$/, "binaryArgControl", ["index"]],
[/^ports must be a list of \{port, description, scheme\}$/, "portsList", []],
[/^ports\[(\d+)\] must be an object$/, "portObject", ["index"]],
[/^ports\[(\d+)\]\.port is required$/, "portRequired", ["index"]],
[/^ports\[(\d+)\]\.port must be an integer$/, "portInteger", ["index"]],
[/^ports\[(\d+)\]\.port must be 1\-65535$/, "portRange", ["index"]],
[/^port (\d+) appears more than once for this app$/, "portDuplicate", ["port"]],
[/^ports\[(\d+)\]\.description has invalid characters$/, "portDescription", ["index"]],
[/^ports\[(\d+)\]\.scheme must be 'http' or 'https'$/, "portScheme", ["index"]],
[/^ports\[(\d+)\]\.web_path must be a valid URL path \(max 255 chars\)$/, "portPath", ["index"]],
[/^ports\[(\d+)\]\.logo_url must be an http\(s\) URL \(max 512 chars\)$/, "portLogo", ["index"]],
[/^ports\[(\d+)\]\.category has invalid characters or is too long$/, "portCategory", ["index"]],
[/^ports\[(\d+)\]\.custom_url must be an http\(s\) URL \(max 512 chars\)$/, "portCustomUrl", ["index"]],
[/^tag_regex exceeds 512 chars$/, "tagRegexLength", []],
[/^could not persist sidecar \(permission\?\)$/, "persistPermission", []],
[/^could not persist sidecar$/, "persist", []],
[/^no apps registered for this vmid$/, "noApps", []],
[/^app_id '([\s\S]+)' not found$/, "appMissing", ["appId"]],
[/^app not found$/, "appNotFound", []],
]
export function localizeAppEditorError(message: string | null | undefined, t: Translate): string {
if (!message) return ""
for (const [pattern, key, names] of RULES) {
const match = pattern.exec(message)
if (!match) continue
const params = Object.fromEntries(names.map((name, index) => [name, match[index + 1]]))
return t(`vmLxc.appEditor.errors.${key}`, params)
}
return message
}