mirror of
https://github.com/kmvan/x-prober.git
synced 2026-08-12 22:21:49 +08:00
adjust types
adjust xconfig.toml
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
allowBuilds:
|
||||
'@parcel/watcher': true
|
||||
core-js: true
|
||||
esbuild: true
|
||||
minimumReleaseAgeExclude:
|
||||
- ultracite@7.9.2
|
||||
@@ -0,0 +1,11 @@
|
||||
export type BootstrapPollDataModel = {
|
||||
isDev: boolean;
|
||||
version: string;
|
||||
appName: string;
|
||||
appUrl: string;
|
||||
appConfigUrls: string[];
|
||||
appConfigUrlDev: string;
|
||||
authorUrl: string;
|
||||
authorName: string;
|
||||
authorization: string;
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
export type BrowserBenchmarkMarksProps = {
|
||||
js: number;
|
||||
dom: number;
|
||||
canvas: number;
|
||||
};
|
||||
export type BrowserBenchmarkProps = {
|
||||
id: string;
|
||||
name: string;
|
||||
version: string;
|
||||
ua: string;
|
||||
date: string;
|
||||
total: number;
|
||||
detail: BrowserBenchmarkMarksProps;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export const ButtonStatus = {
|
||||
Error: "error",
|
||||
Loading: "loading",
|
||||
Pointer: "pointer",
|
||||
Warning: "warning",
|
||||
} as const;
|
||||
export type ButtonStatusKey = keyof typeof ButtonStatus;
|
||||
export type ButtonStatusValue =
|
||||
(typeof ButtonStatus)[keyof typeof ButtonStatus];
|
||||
@@ -0,0 +1,13 @@
|
||||
export type ConfigProps = {
|
||||
APP_VERSION: string;
|
||||
APP_NAME: string;
|
||||
APP_URL: string;
|
||||
AUTHOR_URL: string;
|
||||
UPDATE_PHP_URLS: string[];
|
||||
APP_CONFIG_URLS: string[];
|
||||
BENCHMARKS_URLS: string[];
|
||||
APP_CONFIG_URL_DEV: string;
|
||||
AUTHOR_NAME: string;
|
||||
LATEST_PHP_STABLE_VERSION: string;
|
||||
LATEST_NGINX_STABLE_VERSION: string;
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export type DatabasePollDataProps = Record<string, string | boolean>;
|
||||
@@ -0,0 +1,8 @@
|
||||
export type DiskUsageItemProps = {
|
||||
id: string;
|
||||
total: number;
|
||||
free: number;
|
||||
};
|
||||
export type DiskUsagePollDataProps = {
|
||||
items: DiskUsageItemProps[];
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export type LocationProps = {
|
||||
continent: string;
|
||||
country: string;
|
||||
city: string;
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { FC } from "react";
|
||||
|
||||
export type ModuleProps = {
|
||||
id: string;
|
||||
content: FC;
|
||||
nav: FC;
|
||||
};
|
||||
export type SortedModuleProps = {
|
||||
id: string;
|
||||
priority: number;
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
import { useMemo } from "react";
|
||||
import { useShallow } from "zustand/react/shallow";
|
||||
import { usePollStore } from "@/Components/Poll/components/store.ts";
|
||||
import type { PollData } from "@/Components/Poll/components/types.ts";
|
||||
import { presetModules } from "./preset.ts";
|
||||
import { useModuleStore } from "./store.ts";
|
||||
import type { ModuleProps } from "./types.ts";
|
||||
|
||||
export const useAvailableModules = (): ModuleProps[] => {
|
||||
// 1. 获取完整的优先级顺序
|
||||
const priorities = useModuleStore((s) => s.priorities);
|
||||
// 2. 获取服务端的有效性凭证
|
||||
const pollData = usePollStore(useShallow((s) => s.pollData));
|
||||
|
||||
// 3. 使用 useMemo 缓存计算结果,只有当底层数据改变时才重新计算
|
||||
const available = useMemo(() => {
|
||||
if (!pollData) {
|
||||
return [];
|
||||
}
|
||||
const maps = new Map(presetModules.map((item) => [item.id, item]));
|
||||
return priorities
|
||||
.map((id) => maps.get(id))
|
||||
.filter(
|
||||
(n): n is ModuleProps =>
|
||||
!!n && Object.hasOwn(pollData as PollData, n.id)
|
||||
);
|
||||
}, [priorities, pollData]);
|
||||
|
||||
return available;
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
export type MyInfoPollDataProps = {
|
||||
ipv4: string;
|
||||
ipv6: string;
|
||||
phpLanguage: string;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
export type NetworkStatsItemProps = {
|
||||
id: string;
|
||||
rx: number;
|
||||
tx: number;
|
||||
};
|
||||
export type NetworkStatsPollDataProps = {
|
||||
networks: NetworkStatsItemProps[];
|
||||
timestamp: number;
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { PollData } from "@/Components/Poll/components/types";
|
||||
|
||||
export type NodesItemProps = {
|
||||
id: string;
|
||||
loading: boolean;
|
||||
status: number;
|
||||
data: PollData | null;
|
||||
};
|
||||
export type NodesPollDataProps = {
|
||||
nodesIds: string[];
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
export type PhpExtensionsPollDataProps = {
|
||||
redis: boolean;
|
||||
sqlite3: boolean;
|
||||
memcache: boolean;
|
||||
memcached: boolean;
|
||||
opcache: boolean;
|
||||
opcacheEnabled: boolean;
|
||||
opcacheJitEnabled: boolean;
|
||||
swoole: boolean;
|
||||
imagick: boolean;
|
||||
gmagick: boolean;
|
||||
exif: boolean;
|
||||
fileinfo: boolean;
|
||||
simplexml: boolean;
|
||||
sockets: boolean;
|
||||
mysqli: boolean;
|
||||
zip: boolean;
|
||||
mbstring: boolean;
|
||||
phalcon: boolean;
|
||||
xdebug: boolean;
|
||||
zendOptimizer: boolean;
|
||||
ionCube: boolean;
|
||||
sourceGuardian: boolean;
|
||||
ldap: boolean;
|
||||
curl: boolean;
|
||||
loadedExtensions: string[];
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
export type PhpInfoPollDataProps = {
|
||||
phpVersion: string;
|
||||
sapi: string;
|
||||
displayErrors: boolean;
|
||||
errorReporting: number;
|
||||
memoryLimit: string;
|
||||
postMaxSize: string;
|
||||
uploadMaxFilesize: string;
|
||||
maxInputVars: number;
|
||||
maxExecutionTime: number;
|
||||
defaultSocketTimeout: number;
|
||||
allowUrlFopen: boolean;
|
||||
smtp: boolean;
|
||||
disableFunctions: string[];
|
||||
disableClasses: string[];
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export type ServerToBrowserPingItemProps = {
|
||||
id: string;
|
||||
time: number;
|
||||
};
|
||||
export type ServerToBrowserPingProps = {
|
||||
location: string;
|
||||
items: ServerToBrowserPingItemProps[];
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { ConfigProps } from "@/Components/Config/types";
|
||||
import type { DatabasePollDataProps } from "@/Components/Database/components/types";
|
||||
import type { DiskUsagePollDataProps } from "@/Components/DiskUsage/components/types";
|
||||
import type { MyInfoPollDataProps } from "@/Components/MyInfo/components/types";
|
||||
import type { NetworkStatsPollDataProps } from "@/Components/NetworkStats/components/types";
|
||||
import type { NodesPollDataProps } from "@/Components/Nodes/components/types";
|
||||
import type { PhpExtensionsPollDataProps } from "@/Components/PhpExtensions/components/types";
|
||||
import type { PhpInfoPollDataProps } from "@/Components/PhpInfo/components/types";
|
||||
import type { ServerInfoPollDataProps } from "@/Components/ServerInfo/components/types";
|
||||
import type { ServerStatusPollDataProps } from "@/Components/ServerStatus/components/types";
|
||||
import type { TemperatureSensorPollDataProps } from "@/Components/TemperatureSensor/components/types";
|
||||
import type { UserConfigProps } from "@/Components/UserConfig/types";
|
||||
|
||||
export type PollData = {
|
||||
config: ConfigProps | null;
|
||||
userConfig: UserConfigProps | null;
|
||||
database: DatabasePollDataProps | null;
|
||||
myInfo: MyInfoPollDataProps | null;
|
||||
phpInfo: PhpInfoPollDataProps | null;
|
||||
diskUsage: DiskUsagePollDataProps | null;
|
||||
networkStats: NetworkStatsPollDataProps | null;
|
||||
phpExtensions: PhpExtensionsPollDataProps | null;
|
||||
serverStatus: ServerStatusPollDataProps | null;
|
||||
serverInfo: ServerInfoPollDataProps | null;
|
||||
nodes: NodesPollDataProps | null;
|
||||
temperatureSensor: TemperatureSensorPollDataProps | null;
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
export type ServerBenchmarkMarksProps = {
|
||||
cpu: number;
|
||||
read: number;
|
||||
write: number;
|
||||
};
|
||||
export type ServerBenchmarkProps = {
|
||||
id: string;
|
||||
name: string;
|
||||
url: string;
|
||||
date: string;
|
||||
probeUrl: string;
|
||||
binUrl: string;
|
||||
total: number;
|
||||
detail: ServerBenchmarkMarksProps;
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
export type ServerInfoUptimeProps = {
|
||||
days: number;
|
||||
hours: number;
|
||||
mins: number;
|
||||
secs: number;
|
||||
};
|
||||
export type ServerInfoPollDataProps = {
|
||||
serverName: string;
|
||||
serverUtcTime: string;
|
||||
serverTime: string;
|
||||
localIpv4: string;
|
||||
localIpv6: string;
|
||||
serverUptime: ServerInfoUptimeProps;
|
||||
serverIp: string;
|
||||
serverSoftware: string;
|
||||
phpVersion: string;
|
||||
cpuModel: string;
|
||||
serverOs: string;
|
||||
scriptPath: string;
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
export type ServerStatusUsageProps = {
|
||||
max: number;
|
||||
value: number;
|
||||
};
|
||||
export type ServerStatusCpuUsageProps = {
|
||||
usage: number;
|
||||
idle: number;
|
||||
sys: number;
|
||||
user: number;
|
||||
};
|
||||
export type ServerStatusPollDataProps = {
|
||||
sysLoad: number[];
|
||||
cpuUsage: ServerStatusCpuUsageProps;
|
||||
memRealUsage: ServerStatusUsageProps;
|
||||
memBuffers: ServerStatusUsageProps;
|
||||
memCached: ServerStatusUsageProps;
|
||||
swapUsage: ServerStatusUsageProps;
|
||||
swapCached: ServerStatusUsageProps;
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export type TemperatureSensorItemProps = {
|
||||
id: string;
|
||||
name: string;
|
||||
celsius: number;
|
||||
};
|
||||
export type TemperatureSensorPollDataProps = {
|
||||
items: TemperatureSensorItemProps[];
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
import { useShallow } from "zustand/react/shallow";
|
||||
import { useConfigStore } from "@/Components/Config/store";
|
||||
import { gettext } from "@/Components/Language";
|
||||
import { template } from "@/Components/Utils/components/template";
|
||||
import { useUpdaterStore } from "./store";
|
||||
|
||||
export const useUpdateNotiText = (): string => {
|
||||
const { isUpdating, hasUpdateError, targetVersion } = useUpdaterStore(
|
||||
useShallow((s) => ({
|
||||
isUpdating: s.isUpdating,
|
||||
hasUpdateError: s.hasUpdateError,
|
||||
targetVersion: s.targetVersion,
|
||||
}))
|
||||
);
|
||||
const AppVersion = useConfigStore((s) => s?.pollData?.APP_VERSION ?? "-");
|
||||
if (isUpdating) {
|
||||
return gettext("⏳ Updating, please wait a second...");
|
||||
}
|
||||
if (hasUpdateError) {
|
||||
return gettext("❌ Update error, click here to try again?");
|
||||
}
|
||||
if (targetVersion) {
|
||||
return template(
|
||||
gettext("✨ Found new version: {{oldVersion}} ⇢ {{newVersion}}"),
|
||||
{
|
||||
oldVersion: AppVersion,
|
||||
newVersion: targetVersion,
|
||||
}
|
||||
);
|
||||
}
|
||||
return "";
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
export const UserConfigDisableFeature = {
|
||||
Database: "database",
|
||||
DiskUsage: "diskUsage",
|
||||
MyInfo: "myInfo",
|
||||
MyServerBenchmark: "myServerBenchmark",
|
||||
NetworkStats: "networkStats",
|
||||
PhpDisabledClasses: "phpDisabledClasses",
|
||||
PhpDisabledFunctions: "phpDisabledFunctions",
|
||||
PhpExtensions: "phpExtensions",
|
||||
PhpExtensionsLoaded: "phpExtensionsLoaded",
|
||||
PhpInfo: "phpInfo",
|
||||
PhpInfoDetail: "phpInfoDetail",
|
||||
Ping: "ping",
|
||||
ServerInfo: "serverInfo",
|
||||
ServerIp: "serverIp",
|
||||
ServerStatus: "serverStatus",
|
||||
} as const;
|
||||
export type UserConfigDisableFeatureKey = keyof typeof UserConfigDisableFeature;
|
||||
export type UserConfigDisableFeatureValue =
|
||||
(typeof UserConfigDisableFeature)[keyof typeof UserConfigDisableFeature];
|
||||
export type UserConfigNodeProps = [nodeName: string, url: string];
|
||||
export type UserConfigProps = {
|
||||
serverBenchmarkCd?: number;
|
||||
nodes?: UserConfigNodeProps[];
|
||||
disabled?: UserConfigDisableFeatureKey;
|
||||
};
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace InnStudio\Prober\Components\Utils;
|
||||
|
||||
final class UtilsTomlParser
|
||||
{
|
||||
public static function parse($toml_string)
|
||||
{
|
||||
$result = [];
|
||||
$lines = explode("\n", $toml_string);
|
||||
$current_group = &$result;
|
||||
|
||||
foreach ($lines as $line_num => $line) {
|
||||
$line = trim($line);
|
||||
|
||||
if ('' === $line || '#' === $line[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('[' === $line[0] && ']' === substr($line, -1)) {
|
||||
$group_name = substr($line, 1, -1);
|
||||
$groups = explode('.', $group_name);
|
||||
|
||||
$current_group = &$result;
|
||||
foreach ($groups as $g) {
|
||||
if ( ! isset($current_group[$g])) {
|
||||
$current_group[$g] = [];
|
||||
}
|
||||
$current_group = &$current_group[$g];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (false !== strpos($line, '=')) {
|
||||
[$key, $value] = explode('=', $line, 2);
|
||||
$key = trim($key);
|
||||
$value = trim($value);
|
||||
|
||||
$parsed_value = self::parse_value($value);
|
||||
$current_group[$key] = $parsed_value;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function parse_value($value)
|
||||
{
|
||||
if (preg_match('/^"(.*)"$/', $value, $matches)) {
|
||||
return str_replace('\\"', '"', $matches[1]);
|
||||
}
|
||||
|
||||
if (preg_match("/^'(.*)'$/", $value, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
if ('true' === $value) {
|
||||
return true;
|
||||
}
|
||||
if ('false' === $value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (preg_match('/^-?\\d+$/', $value)) {
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
if (preg_match('/^-?\\d+\\.\\d+$/', $value)) {
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
if ('[' === $value[0] && ']' === substr($value, -1)) {
|
||||
$inner = trim(substr($value, 1, -1));
|
||||
if ('' === $inner) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$items = [];
|
||||
$current = '';
|
||||
$in_string = false;
|
||||
$string_char = '';
|
||||
$i = 0;
|
||||
$len = \strlen($inner);
|
||||
|
||||
while ($i < $len) {
|
||||
$char = $inner[$i];
|
||||
|
||||
if ( ! $in_string && ('"' === $char || "'" === $char)) {
|
||||
$in_string = true;
|
||||
$string_char = $char;
|
||||
$current .= $char;
|
||||
} elseif ($in_string && $char === $string_char && '\\' !== $inner[$i - 1]) {
|
||||
$in_string = false;
|
||||
$current .= $char;
|
||||
} elseif ( ! $in_string && ',' === $char) {
|
||||
$items[] = self::parse_value(trim($current));
|
||||
$current = '';
|
||||
} else {
|
||||
$current .= $char;
|
||||
}
|
||||
++$i;
|
||||
}
|
||||
|
||||
if ('' !== trim($current)) {
|
||||
$items[] = self::parse_value(trim($current));
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
return trim($value, '"\'');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export type FetchStatus = "loading" | "idel" | "error";
|
||||
@@ -0,0 +1,7 @@
|
||||
export type WindowConfigProps = {
|
||||
IS_DEV: boolean;
|
||||
AUTHORIZATION: string;
|
||||
};
|
||||
export type WindowProps = {
|
||||
GLOBAL_CONFIG: WindowConfigProps;
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
export const PieChartStatus = {
|
||||
High: "high",
|
||||
Low: "low",
|
||||
Medium: "medium",
|
||||
} as const;
|
||||
export type PieChartStatusKey = keyof typeof PieChartStatus;
|
||||
export type PieChartStatusValue =
|
||||
(typeof PieChartStatus)[keyof typeof PieChartStatus];
|
||||
@@ -0,0 +1,50 @@
|
||||
# =============================================================================
|
||||
# X-Prober 配置文件 | X-Prober Configuration
|
||||
# =============================================================================
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 功能开关 | Feature Toggles
|
||||
# -----------------------------------------------------------------------------
|
||||
# 禁用特定功能以增强安全性或减少系统开销。
|
||||
# Disable specific features to improve security or reduce overhead.
|
||||
#
|
||||
# 可用选项 | Available options: serverStatus, diskUsage, networkStats, ping,
|
||||
# serverInfo, phpInfo, phpInfoDetail, phpDisabledFunctions,
|
||||
# phpDisabledClasses, phpExtensions, phpExtensionsLoaded, database,
|
||||
# myServerBenchmark, myInfo, serverIp
|
||||
#
|
||||
# disabled = ["serverIp", "phpInfoDetail"]
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 硬件监控 | Hardware Monitoring
|
||||
# -----------------------------------------------------------------------------
|
||||
# 温度传感器接口地址(例如:树莓派传感器)。
|
||||
# Temperature sensor endpoints (e.g., Raspberry Pi sensors).
|
||||
#
|
||||
# 参考文档 | Reference: /extensions/temperature-sensors/raspberrypi.js
|
||||
#
|
||||
# temperatureSensors = [
|
||||
# "http://localhost:4096"
|
||||
# ]
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 性能测试 | Performance Testing
|
||||
# -----------------------------------------------------------------------------
|
||||
# 服务器基准测试冷却时间(秒),防止频繁测试导致服务器过载。
|
||||
# Cooldown period between server benchmark runs (in seconds).
|
||||
# Prevents excessive load from frequent testing.
|
||||
#
|
||||
# serverBenchmarkCd = 30
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# 多节点聚合 | Multi-Node Aggregation
|
||||
# -----------------------------------------------------------------------------
|
||||
# 定义其他 X-Prober 节点,用于聚合仪表盘展示。
|
||||
# Define additional X-Prober nodes for aggregated dashboard view.
|
||||
#
|
||||
# 格式 | Format: ["显示名称", "节点地址"] | ["display-name", "node-url"]
|
||||
#
|
||||
# nodes = [
|
||||
# ["node-1", "http://localhost:5173"],
|
||||
# ["node-3", "http://localhost:5173"]
|
||||
# ]
|
||||
Reference in New Issue
Block a user