@astralyn/sash 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +22 -7
- package/THIRD_PARTY_NOTICES.md +9 -0
- package/dist/api.js +14 -45
- package/dist/app-state.js +99 -0
- package/dist/autostart/command.js +24 -0
- package/dist/autostart/context.js +43 -0
- package/dist/autostart/files.js +60 -0
- package/dist/autostart/installation.js +48 -0
- package/dist/autostart/start.js +47 -0
- package/dist/autostart/windows-registry.js +88 -0
- package/dist/autostart/windows.js +59 -0
- package/dist/autostart-contract.js +31 -0
- package/dist/autostart-entry.js +10 -0
- package/dist/autostart.js +69 -0
- package/dist/cli.js +11 -11
- package/dist/commands/auto.js +15 -0
- package/dist/commands/lifecycle.js +5 -31
- package/dist/commands/logs.js +11 -4
- package/dist/commands/shared.js +2 -4
- package/dist/commands/status.js +6 -7
- package/dist/commands/update.js +7 -3
- package/dist/commands/web.js +19 -27
- package/dist/contracts.js +171 -335
- package/dist/core-config-validation.js +22 -38
- package/dist/core-update.js +126 -762
- package/dist/core.js +20 -46
- package/dist/daemon/app.js +132 -113
- package/dist/daemon/context.js +13 -7
- package/dist/daemon/entry.js +21 -38
- package/dist/daemon/errors.js +6 -1
- package/dist/daemon/handlers/autostart.js +18 -0
- package/dist/daemon/handlers/core.js +32 -9
- package/dist/daemon/handlers/daemon.js +32 -6
- package/dist/daemon/handlers/profiles.js +12 -2
- package/dist/daemon/handlers/settings.js +9 -36
- package/dist/daemon/router.js +40 -27
- package/dist/daemon/scheduler.js +3 -1
- package/dist/daemon/server.js +6 -3
- package/dist/daemon/web-auth.js +52 -0
- package/dist/daemon-auth.js +2 -2
- package/dist/daemon-client.js +18 -2
- package/dist/daemon-http.js +7 -0
- package/dist/daemon-lifecycle.js +19 -196
- package/dist/github.js +7 -2
- package/dist/http.js +7 -5
- package/dist/log-follow.js +2 -1
- package/dist/mihomo-config.js +7 -9
- package/dist/paths.js +5 -7
- package/dist/profile-model.js +87 -0
- package/dist/profile-service.js +250 -587
- package/dist/profiles.js +43 -171
- package/dist/runtime-lifecycle.js +112 -194
- package/dist/runtime-owner.js +37 -76
- package/dist/sash-client.js +63 -21
- package/dist/settings-service.js +29 -228
- package/dist/settings.js +61 -285
- package/dist/status.js +24 -40
- package/dist/supervisor.js +1 -14
- package/dist/sysproxy/common.js +5 -45
- package/dist/sysproxy/factory.js +24 -65
- package/dist/sysproxy/snapshot.js +24 -257
- package/dist/sysproxy.js +1 -4
- package/dist/system-proxy-manager.js +37 -35
- package/dist/ui/assets/{ConnectionsView-DNGmZBSU.js → ConnectionsView-BgXQM6Z4.js} +1 -1
- package/dist/ui/assets/{LogsView-fSiaxQ13.js → LogsView-2f542P8z.js} +1 -1
- package/dist/ui/assets/{PaginationFooter-B3kHzRfB.js → PaginationFooter-cj1tcZej.js} +1 -1
- package/dist/ui/assets/ProfileEditorDialog-C9M8uKZC.css +1 -0
- package/dist/ui/assets/ProfileEditorDialog-DD4y4GBC.js +14 -0
- package/dist/ui/assets/ProfilesView-BXU2DOA7.css +1 -0
- package/dist/ui/assets/ProfilesView-DNnzYIEY.js +7 -0
- package/dist/ui/assets/{RulesView-D9vZBiJ1.js → RulesView-CtKvlckZ.js} +1 -1
- package/dist/ui/assets/SettingsView-BaeKFF_N.js +1 -0
- package/dist/ui/assets/SettingsView-CWjIe05v.css +1 -0
- package/dist/ui/assets/{0be242294f7d791af850c6df38ac78a0-2cL6Ntwf.woff2 → e2a57555d97d0b02b45d9418eb6ee295-D9nhF3rM.woff2} +0 -0
- package/dist/ui/assets/index-CBInDvdJ.js +19 -0
- package/dist/ui/assets/index-mOLy7fkB.css +1 -0
- package/dist/ui/assets/{theme-BNq4FkXS.js → theme-D40MF8cQ.js} +1 -1
- package/dist/ui/index.html +2 -2
- package/dist/web-bootstrap.js +113 -0
- package/docs/architecture-proposal.md +109 -0
- package/docs/autostart.md +101 -0
- package/docs/backend.md +92 -216
- package/docs/frontend.md +61 -97
- package/docs/usage.md +88 -186
- package/package.json +10 -6
- package/dist/commands/upgrade.js +0 -43
- package/dist/core-install-transaction.js +0 -114
- package/dist/core-update-coordination.js +0 -105
- package/dist/core-update-service.js +0 -245
- package/dist/managed-state-transaction.js +0 -377
- package/dist/offline-mutation.js +0 -58
- package/dist/profile-migration.js +0 -101
- package/dist/runtime-recovery.js +0 -31
- package/dist/sysproxy/darwin.js +0 -287
- package/dist/sysproxy/gnome.js +0 -181
- package/dist/sysproxy/legacy.js +0 -58
- package/dist/tun-guidance.js +0 -11
- package/dist/ui/assets/CodeEditorModal-6m0TJWyF.css +0 -1
- package/dist/ui/assets/CodeEditorModal-CFEnWsyh.js +0 -14
- package/dist/ui/assets/ProfileEditorDialog-BydoZthX.js +0 -1
- package/dist/ui/assets/ProfilesView-Btc1DOxE.js +0 -2
- package/dist/ui/assets/ProfilesView-ByqdFNHN.css +0 -1
- package/dist/ui/assets/SettingsFileDialog-CNFEAVs4.js +0 -1
- package/dist/ui/assets/SettingsView-BlDhZkXQ.js +0 -2
- package/dist/ui/assets/SettingsView-CngS3vBM.css +0 -1
- package/dist/ui/assets/index-B61V60w_.js +0 -19
- package/dist/ui/assets/index-bkyxJG8J.css +0 -1
package/dist/sysproxy/factory.js
CHANGED
|
@@ -1,71 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { applyDarwinSnapshot, captureDarwinSnapshot, createDarwinTarget, darwinState, } from "./darwin.js";
|
|
3
|
-
import { applyLinuxSnapshot, captureLinuxSnapshot, createLinuxTarget, linuxState, } from "./gnome.js";
|
|
4
|
-
import { parseSystemProxySnapshot, snapshotsCompatible, snapshotsEquivalent } from "./snapshot.js";
|
|
1
|
+
import { snapshotsCompatible, snapshotsEquivalent } from "./snapshot.js";
|
|
5
2
|
import { applyWindowsSnapshot, captureWindowsSnapshot, createWindowsTarget, windowsState, } from "./windows.js";
|
|
6
|
-
function
|
|
3
|
+
export function createSystemProxyBackend(platform = process.platform) {
|
|
4
|
+
if (platform === "win32")
|
|
5
|
+
return {
|
|
6
|
+
supported: true,
|
|
7
|
+
capture: captureWindowsSnapshot,
|
|
8
|
+
createTarget: createWindowsTarget,
|
|
9
|
+
apply: applyWindowsSnapshot,
|
|
10
|
+
equivalent: snapshotsEquivalent,
|
|
11
|
+
compatible: snapshotsCompatible,
|
|
12
|
+
state: windowsState,
|
|
13
|
+
};
|
|
14
|
+
const unavailable = () => {
|
|
15
|
+
throw new Error("System proxy integration is available on Windows only");
|
|
16
|
+
};
|
|
7
17
|
return {
|
|
8
|
-
supported:
|
|
9
|
-
capture: () =>
|
|
10
|
-
createTarget:
|
|
11
|
-
apply: (
|
|
18
|
+
supported: false,
|
|
19
|
+
capture: async () => unavailable(),
|
|
20
|
+
createTarget: unavailable,
|
|
21
|
+
apply: async () => unavailable(),
|
|
12
22
|
equivalent: snapshotsEquivalent,
|
|
13
23
|
compatible: snapshotsCompatible,
|
|
14
|
-
state: (
|
|
24
|
+
state: () => ({
|
|
25
|
+
supported: false,
|
|
26
|
+
enabled: false,
|
|
27
|
+
details: "System proxy integration is available on Windows only",
|
|
28
|
+
}),
|
|
15
29
|
};
|
|
16
30
|
}
|
|
17
|
-
class UnsupportedSystemProxyBackend {
|
|
18
|
-
details;
|
|
19
|
-
supported = false;
|
|
20
|
-
constructor(details) {
|
|
21
|
-
this.details = details;
|
|
22
|
-
}
|
|
23
|
-
async capture() {
|
|
24
|
-
throw new Error(this.details);
|
|
25
|
-
}
|
|
26
|
-
createTarget(_original, _opts) {
|
|
27
|
-
throw new Error(this.details);
|
|
28
|
-
}
|
|
29
|
-
async apply(_snapshot) {
|
|
30
|
-
throw new Error(this.details);
|
|
31
|
-
}
|
|
32
|
-
equivalent(a, b) {
|
|
33
|
-
return snapshotsEquivalent(a, b);
|
|
34
|
-
}
|
|
35
|
-
compatible(_current, _original, _target) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
state(snapshot) {
|
|
39
|
-
parseSystemProxySnapshot(snapshot);
|
|
40
|
-
return { supported: false, enabled: false, details: this.details };
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
export function createSystemProxyBackend(platform = process.platform) {
|
|
44
|
-
switch (platform) {
|
|
45
|
-
case "win32":
|
|
46
|
-
return createSupportedBackend({
|
|
47
|
-
capture: captureWindowsSnapshot,
|
|
48
|
-
createTarget: createWindowsTarget,
|
|
49
|
-
apply: applyWindowsSnapshot,
|
|
50
|
-
state: windowsState,
|
|
51
|
-
});
|
|
52
|
-
case "darwin":
|
|
53
|
-
return createSupportedBackend({
|
|
54
|
-
capture: captureDarwinSnapshot,
|
|
55
|
-
createTarget: createDarwinTarget,
|
|
56
|
-
apply: applyDarwinSnapshot,
|
|
57
|
-
state: darwinState,
|
|
58
|
-
});
|
|
59
|
-
case "linux":
|
|
60
|
-
return isSystemProxySupported("linux")
|
|
61
|
-
? createSupportedBackend({
|
|
62
|
-
capture: captureLinuxSnapshot,
|
|
63
|
-
createTarget: createLinuxTarget,
|
|
64
|
-
apply: applyLinuxSnapshot,
|
|
65
|
-
state: linuxState,
|
|
66
|
-
})
|
|
67
|
-
: new UnsupportedSystemProxyBackend("gsettings not available; desktop proxy configuration unsupported");
|
|
68
|
-
default:
|
|
69
|
-
return new UnsupportedSystemProxyBackend(`unsupported platform: ${platform}`);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,163 +1,24 @@
|
|
|
1
|
-
import { hasExactOwnKeys } from "../json-shape.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
throw new Error(`Invalid system proxy snapshot: ${label} has unexpected fields`);
|
|
11
|
-
}
|
|
12
|
-
return value;
|
|
13
|
-
}
|
|
14
|
-
function parseDarwinSnapshotSetting(value, label) {
|
|
15
|
-
const record = hasExactKeys(value, ["enabled", "server", "port", "authenticated"], label);
|
|
16
|
-
if (typeof record.enabled !== "boolean") {
|
|
17
|
-
throw new Error(`Invalid system proxy snapshot: ${label}.enabled must be a boolean`);
|
|
18
|
-
}
|
|
19
|
-
if (typeof record.authenticated !== "boolean") {
|
|
20
|
-
throw new Error(`Invalid system proxy snapshot: ${label}.authenticated must be a boolean`);
|
|
21
|
-
}
|
|
22
|
-
return {
|
|
23
|
-
enabled: record.enabled,
|
|
24
|
-
server: parseProxyString(record.server, `${label}.server`),
|
|
25
|
-
port: parseSnapshotPort(record.port, `${label}.port`),
|
|
26
|
-
authenticated: record.authenticated,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
function parseDarwinAutoSetting(value, label) {
|
|
30
|
-
const record = hasExactKeys(value, ["enabled", "url"], label);
|
|
31
|
-
if (typeof record.enabled !== "boolean") {
|
|
32
|
-
throw new Error(`Invalid system proxy snapshot: ${label}.enabled must be a boolean`);
|
|
33
|
-
}
|
|
34
|
-
return {
|
|
35
|
-
enabled: record.enabled,
|
|
36
|
-
url: parseProxyString(record.url, `${label}.url`),
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
function parseLinuxEndpoint(value, label) {
|
|
40
|
-
const record = hasExactKeys(value, ["host", "port"], label);
|
|
41
|
-
return {
|
|
42
|
-
host: parseProxyString(record.host, `${label}.host`),
|
|
43
|
-
port: parseSnapshotPort(record.port, `${label}.port`),
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
function parseWindowsSnapshot(value) {
|
|
47
|
-
const record = hasExactKeys(value, [
|
|
48
|
-
"version",
|
|
49
|
-
"platform",
|
|
50
|
-
"proxyEnable",
|
|
51
|
-
"proxyServer",
|
|
52
|
-
"proxyOverride",
|
|
53
|
-
"autoConfigUrl",
|
|
54
|
-
"autoDetect",
|
|
55
|
-
], "Windows snapshot");
|
|
56
|
-
if (record.version !== SYSTEM_PROXY_SNAPSHOT_VERSION || record.platform !== "win32") {
|
|
57
|
-
throw new Error("Invalid system proxy snapshot: expected version 1 Windows snapshot");
|
|
58
|
-
}
|
|
59
|
-
if (record.proxyServer !== null && typeof record.proxyServer !== "string") {
|
|
60
|
-
throw new Error("Invalid system proxy snapshot: proxyServer must be a string or null");
|
|
61
|
-
}
|
|
62
|
-
if (record.proxyOverride !== null && typeof record.proxyOverride !== "string") {
|
|
63
|
-
throw new Error("Invalid system proxy snapshot: proxyOverride must be a string or null");
|
|
64
|
-
}
|
|
65
|
-
if (record.autoConfigUrl !== null && typeof record.autoConfigUrl !== "string") {
|
|
66
|
-
throw new Error("Invalid system proxy snapshot: autoConfigUrl must be a string or null");
|
|
1
|
+
import { hasExactOwnKeys, isPlainObject } from "../json-shape.js";
|
|
2
|
+
import { parseProxyEnable, parseProxyString } from "./common.js";
|
|
3
|
+
const MANAGED_KEYS = ["proxyEnable", "proxyServer", "proxyOverride", "autoConfigUrl"];
|
|
4
|
+
export function parseSystemProxySnapshot(value) {
|
|
5
|
+
if (!isPlainObject(value) ||
|
|
6
|
+
!hasExactOwnKeys(value, ["version", "platform", ...MANAGED_KEYS, "autoDetect"]) ||
|
|
7
|
+
value.version !== 1 ||
|
|
8
|
+
value.platform !== "win32") {
|
|
9
|
+
throw new Error("Invalid system proxy snapshot: expected a version 1 Windows snapshot");
|
|
67
10
|
}
|
|
68
11
|
return {
|
|
69
|
-
version:
|
|
12
|
+
version: 1,
|
|
70
13
|
platform: "win32",
|
|
71
|
-
proxyEnable: parseProxyEnable(
|
|
72
|
-
proxyServer:
|
|
73
|
-
proxyOverride:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
autoConfigUrl: record.autoConfigUrl === null
|
|
77
|
-
? null
|
|
78
|
-
: parseProxyString(record.autoConfigUrl, "autoConfigUrl"),
|
|
79
|
-
autoDetect: parseProxyEnable(record.autoDetect),
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
function parseDarwinSnapshot(value) {
|
|
83
|
-
const record = hasExactKeys(value, ["version", "platform", "services"], "macOS snapshot");
|
|
84
|
-
if (record.version !== SYSTEM_PROXY_SNAPSHOT_VERSION || record.platform !== "darwin") {
|
|
85
|
-
throw new Error("Invalid system proxy snapshot: expected version 1 macOS snapshot");
|
|
86
|
-
}
|
|
87
|
-
if (!Array.isArray(record.services)) {
|
|
88
|
-
throw new Error("Invalid system proxy snapshot: services must be an array");
|
|
89
|
-
}
|
|
90
|
-
if (record.services.length > MAX_NETWORK_SERVICES) {
|
|
91
|
-
throw new Error("Invalid system proxy snapshot: services has too many entries");
|
|
92
|
-
}
|
|
93
|
-
const services = record.services.map((value, index) => {
|
|
94
|
-
const service = hasExactKeys(value, ["service", "web", "secureWeb", "socks", "auto"], `services[${index}]`);
|
|
95
|
-
return {
|
|
96
|
-
service: parseServiceName(service.service, `services[${index}].service`),
|
|
97
|
-
web: parseDarwinSnapshotSetting(service.web, `services[${index}].web`),
|
|
98
|
-
secureWeb: parseDarwinSnapshotSetting(service.secureWeb, `services[${index}].secureWeb`),
|
|
99
|
-
socks: parseDarwinSnapshotSetting(service.socks, `services[${index}].socks`),
|
|
100
|
-
auto: parseDarwinAutoSetting(service.auto, `services[${index}].auto`),
|
|
101
|
-
};
|
|
102
|
-
});
|
|
103
|
-
services.sort((a, b) => compareStrings(a.service, b.service));
|
|
104
|
-
for (let index = 1; index < services.length; index++) {
|
|
105
|
-
if (services[index - 1]?.service === services[index]?.service) {
|
|
106
|
-
throw new Error("Invalid system proxy snapshot: services must not contain duplicate names");
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return {
|
|
110
|
-
version: SYSTEM_PROXY_SNAPSHOT_VERSION,
|
|
111
|
-
platform: "darwin",
|
|
112
|
-
services,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
function parseLinuxSnapshot(value) {
|
|
116
|
-
const record = hasExactKeys(value, [
|
|
117
|
-
"version",
|
|
118
|
-
"platform",
|
|
119
|
-
"mode",
|
|
120
|
-
"autoConfigUrl",
|
|
121
|
-
"httpUseAuthentication",
|
|
122
|
-
"http",
|
|
123
|
-
"https",
|
|
124
|
-
"socks",
|
|
125
|
-
], "Linux snapshot");
|
|
126
|
-
if (record.version !== SYSTEM_PROXY_SNAPSHOT_VERSION || record.platform !== "linux") {
|
|
127
|
-
throw new Error("Invalid system proxy snapshot: expected version 1 Linux snapshot");
|
|
128
|
-
}
|
|
129
|
-
if (record.mode !== "none" && record.mode !== "manual" && record.mode !== "auto") {
|
|
130
|
-
throw new Error("Invalid system proxy snapshot: mode must be none, manual, or auto");
|
|
131
|
-
}
|
|
132
|
-
if (typeof record.httpUseAuthentication !== "boolean") {
|
|
133
|
-
throw new Error("Invalid system proxy snapshot: httpUseAuthentication must be a boolean");
|
|
134
|
-
}
|
|
135
|
-
return {
|
|
136
|
-
version: SYSTEM_PROXY_SNAPSHOT_VERSION,
|
|
137
|
-
platform: "linux",
|
|
138
|
-
mode: record.mode,
|
|
139
|
-
autoConfigUrl: parseProxyString(record.autoConfigUrl, "autoConfigUrl"),
|
|
140
|
-
httpUseAuthentication: record.httpUseAuthentication,
|
|
141
|
-
http: parseLinuxEndpoint(record.http, "http"),
|
|
142
|
-
https: parseLinuxEndpoint(record.https, "https"),
|
|
143
|
-
socks: parseLinuxEndpoint(record.socks, "socks"),
|
|
14
|
+
proxyEnable: parseProxyEnable(value.proxyEnable),
|
|
15
|
+
proxyServer: value.proxyServer === null ? null : parseProxyString(value.proxyServer, "proxyServer"),
|
|
16
|
+
proxyOverride: value.proxyOverride === null ? null : parseProxyString(value.proxyOverride, "proxyOverride"),
|
|
17
|
+
autoConfigUrl: value.autoConfigUrl === null ? null : parseProxyString(value.autoConfigUrl, "autoConfigUrl"),
|
|
18
|
+
autoDetect: parseProxyEnable(value.autoDetect),
|
|
144
19
|
};
|
|
145
20
|
}
|
|
146
|
-
export
|
|
147
|
-
if (!isPlainObject(value)) {
|
|
148
|
-
throw new Error("Invalid system proxy snapshot: root must be a plain object");
|
|
149
|
-
}
|
|
150
|
-
switch (value.platform) {
|
|
151
|
-
case "win32":
|
|
152
|
-
return parseWindowsSnapshot(value);
|
|
153
|
-
case "darwin":
|
|
154
|
-
return parseDarwinSnapshot(value);
|
|
155
|
-
case "linux":
|
|
156
|
-
return parseLinuxSnapshot(value);
|
|
157
|
-
default:
|
|
158
|
-
throw new Error("Invalid system proxy snapshot: platform must be win32, darwin, or linux");
|
|
159
|
-
}
|
|
160
|
-
}
|
|
21
|
+
export { parseSystemProxySnapshot as windowsSnapshot };
|
|
161
22
|
export function isSystemProxySnapshot(value) {
|
|
162
23
|
try {
|
|
163
24
|
parseSystemProxySnapshot(value);
|
|
@@ -167,116 +28,22 @@ export function isSystemProxySnapshot(value) {
|
|
|
167
28
|
return false;
|
|
168
29
|
}
|
|
169
30
|
}
|
|
170
|
-
export function
|
|
171
|
-
const snapshot = parseSystemProxySnapshot(value);
|
|
172
|
-
if (snapshot.platform !== "win32") {
|
|
173
|
-
throw new Error("Invalid system proxy snapshot: expected Windows snapshot");
|
|
174
|
-
}
|
|
175
|
-
return snapshot;
|
|
176
|
-
}
|
|
177
|
-
export function darwinSnapshot(value) {
|
|
178
|
-
const snapshot = parseSystemProxySnapshot(value);
|
|
179
|
-
if (snapshot.platform !== "darwin") {
|
|
180
|
-
throw new Error("Invalid system proxy snapshot: expected macOS snapshot");
|
|
181
|
-
}
|
|
182
|
-
return snapshot;
|
|
183
|
-
}
|
|
184
|
-
export function linuxSnapshot(value) {
|
|
185
|
-
const snapshot = parseSystemProxySnapshot(value);
|
|
186
|
-
if (snapshot.platform !== "linux") {
|
|
187
|
-
throw new Error("Invalid system proxy snapshot: expected Linux snapshot");
|
|
188
|
-
}
|
|
189
|
-
return snapshot;
|
|
190
|
-
}
|
|
191
|
-
function normalizeForEquivalence(snapshot) {
|
|
192
|
-
return snapshot.platform === "win32" ? { ...snapshot, autoDetect: null } : snapshot;
|
|
193
|
-
}
|
|
194
|
-
export function snapshotsEquivalent(a, b) {
|
|
31
|
+
export function snapshotsEquivalent(left, right) {
|
|
195
32
|
try {
|
|
196
|
-
|
|
197
|
-
|
|
33
|
+
const a = parseSystemProxySnapshot(left);
|
|
34
|
+
const b = parseSystemProxySnapshot(right);
|
|
35
|
+
return MANAGED_KEYS.every((key) => a[key] === b[key]);
|
|
198
36
|
}
|
|
199
37
|
catch {
|
|
200
38
|
return false;
|
|
201
39
|
}
|
|
202
40
|
}
|
|
203
|
-
function leafIsCompatible(current, original, target) {
|
|
204
|
-
return current === original || current === target;
|
|
205
|
-
}
|
|
206
|
-
function sameDarwinServices(a, b) {
|
|
207
|
-
if (a.services.length !== b.services.length)
|
|
208
|
-
return false;
|
|
209
|
-
for (let index = 0; index < a.services.length; index++) {
|
|
210
|
-
if (a.services[index]?.service !== b.services[index]?.service)
|
|
211
|
-
return false;
|
|
212
|
-
}
|
|
213
|
-
return true;
|
|
214
|
-
}
|
|
215
|
-
function darwinSettingIsCompatible(current, original, target) {
|
|
216
|
-
return (leafIsCompatible(current.enabled, original.enabled, target.enabled) &&
|
|
217
|
-
leafIsCompatible(current.server, original.server, target.server) &&
|
|
218
|
-
leafIsCompatible(current.port, original.port, target.port) &&
|
|
219
|
-
leafIsCompatible(current.authenticated, original.authenticated, target.authenticated));
|
|
220
|
-
}
|
|
221
|
-
function darwinAutoSettingIsCompatible(current, original, target) {
|
|
222
|
-
return (leafIsCompatible(current.enabled, original.enabled, target.enabled) &&
|
|
223
|
-
leafIsCompatible(current.url, original.url, target.url));
|
|
224
|
-
}
|
|
225
|
-
function linuxEndpointIsCompatible(current, original, target) {
|
|
226
|
-
return (leafIsCompatible(current.host, original.host, target.host) &&
|
|
227
|
-
leafIsCompatible(current.port, original.port, target.port));
|
|
228
|
-
}
|
|
229
41
|
export function snapshotsCompatible(current, original, target) {
|
|
230
42
|
try {
|
|
231
|
-
const
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
parsedCurrent.platform !== parsedTarget.platform) {
|
|
236
|
-
return false;
|
|
237
|
-
}
|
|
238
|
-
switch (parsedCurrent.platform) {
|
|
239
|
-
case "win32":
|
|
240
|
-
if (parsedOriginal.platform !== "win32" || parsedTarget.platform !== "win32") {
|
|
241
|
-
return false;
|
|
242
|
-
}
|
|
243
|
-
return (leafIsCompatible(parsedCurrent.proxyEnable, parsedOriginal.proxyEnable, parsedTarget.proxyEnable) &&
|
|
244
|
-
leafIsCompatible(parsedCurrent.proxyServer, parsedOriginal.proxyServer, parsedTarget.proxyServer) &&
|
|
245
|
-
leafIsCompatible(parsedCurrent.proxyOverride, parsedOriginal.proxyOverride, parsedTarget.proxyOverride) &&
|
|
246
|
-
leafIsCompatible(parsedCurrent.autoConfigUrl, parsedOriginal.autoConfigUrl, parsedTarget.autoConfigUrl));
|
|
247
|
-
case "darwin":
|
|
248
|
-
if (parsedOriginal.platform !== "darwin" || parsedTarget.platform !== "darwin") {
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
|
-
if (!sameDarwinServices(parsedCurrent, parsedOriginal) ||
|
|
252
|
-
!sameDarwinServices(parsedCurrent, parsedTarget)) {
|
|
253
|
-
return false;
|
|
254
|
-
}
|
|
255
|
-
for (let index = 0; index < parsedCurrent.services.length; index++) {
|
|
256
|
-
const currentService = parsedCurrent.services[index];
|
|
257
|
-
const originalService = parsedOriginal.services[index];
|
|
258
|
-
const targetService = parsedTarget.services[index];
|
|
259
|
-
if (!currentService || !originalService || !targetService)
|
|
260
|
-
return false;
|
|
261
|
-
if (!darwinSettingIsCompatible(currentService.web, originalService.web, targetService.web) ||
|
|
262
|
-
!darwinSettingIsCompatible(currentService.secureWeb, originalService.secureWeb, targetService.secureWeb) ||
|
|
263
|
-
!darwinSettingIsCompatible(currentService.socks, originalService.socks, targetService.socks) ||
|
|
264
|
-
!darwinAutoSettingIsCompatible(currentService.auto, originalService.auto, targetService.auto)) {
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return true;
|
|
269
|
-
case "linux":
|
|
270
|
-
if (parsedOriginal.platform !== "linux" || parsedTarget.platform !== "linux") {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
return (leafIsCompatible(parsedCurrent.mode, parsedOriginal.mode, parsedTarget.mode) &&
|
|
274
|
-
leafIsCompatible(parsedCurrent.autoConfigUrl, parsedOriginal.autoConfigUrl, parsedTarget.autoConfigUrl) &&
|
|
275
|
-
leafIsCompatible(parsedCurrent.httpUseAuthentication, parsedOriginal.httpUseAuthentication, parsedTarget.httpUseAuthentication) &&
|
|
276
|
-
linuxEndpointIsCompatible(parsedCurrent.http, parsedOriginal.http, parsedTarget.http) &&
|
|
277
|
-
linuxEndpointIsCompatible(parsedCurrent.https, parsedOriginal.https, parsedTarget.https) &&
|
|
278
|
-
linuxEndpointIsCompatible(parsedCurrent.socks, parsedOriginal.socks, parsedTarget.socks));
|
|
279
|
-
}
|
|
43
|
+
const now = parseSystemProxySnapshot(current);
|
|
44
|
+
const before = parseSystemProxySnapshot(original);
|
|
45
|
+
const after = parseSystemProxySnapshot(target);
|
|
46
|
+
return MANAGED_KEYS.every((key) => now[key] === before[key] || now[key] === after[key]);
|
|
280
47
|
}
|
|
281
48
|
catch {
|
|
282
49
|
return false;
|
package/dist/sysproxy.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
export { isSystemProxySupported } from "./sysproxy/common.js";
|
|
2
|
-
export { parseDarwinAutoProxySetting, parseDarwinProxySetting, parseDarwinServices, } from "./sysproxy/darwin.js";
|
|
3
2
|
export { createSystemProxyBackend } from "./sysproxy/factory.js";
|
|
4
|
-
export { parseGSettingsPort, parseGSettingsString } from "./sysproxy/gnome.js";
|
|
5
|
-
export { createLegacyProxyCleanup, disableLegacySystemProxyIfOwned, } from "./sysproxy/legacy.js";
|
|
6
3
|
export { isSystemProxySnapshot, parseSystemProxySnapshot } from "./sysproxy/snapshot.js";
|
|
7
4
|
export { DEFAULT_BYPASS_LIST, SYSTEM_PROXY_SNAPSHOT_VERSION } from "./sysproxy/types.js";
|
|
8
|
-
export { formatWindowsBypass, parseWindowsRegistryProxyValues
|
|
5
|
+
export { formatWindowsBypass, parseWindowsRegistryProxyValues } from "./sysproxy/windows.js";
|
|
@@ -16,21 +16,6 @@ function hasExactKeys(value, keys) {
|
|
|
16
16
|
throw journalError("root has unexpected fields");
|
|
17
17
|
return value;
|
|
18
18
|
}
|
|
19
|
-
function sameDarwinServiceCollection(a, b) {
|
|
20
|
-
if (a.platform !== "darwin" || b.platform !== "darwin")
|
|
21
|
-
return false;
|
|
22
|
-
if (a.services.length !== b.services.length)
|
|
23
|
-
return false;
|
|
24
|
-
return a.services.every((service, index) => service.service === b.services[index]?.service);
|
|
25
|
-
}
|
|
26
|
-
function journalSnapshotsHaveSameStructure(original, target) {
|
|
27
|
-
if (original.platform !== target.platform)
|
|
28
|
-
return false;
|
|
29
|
-
if (original.platform === "darwin" && target.platform === "darwin") {
|
|
30
|
-
return sameDarwinServiceCollection(original, target);
|
|
31
|
-
}
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
19
|
function parseCreatedAt(value) {
|
|
35
20
|
if (typeof value !== "string" || value.length === 0 || value.length > 128) {
|
|
36
21
|
throw journalError("createdAt must be a non-empty ISO timestamp");
|
|
@@ -49,12 +34,10 @@ export function parseSystemProxyJournal(value) {
|
|
|
49
34
|
"original",
|
|
50
35
|
"target",
|
|
51
36
|
]);
|
|
52
|
-
if (record.schemaVersion !==
|
|
53
|
-
throw journalError("schemaVersion must be
|
|
37
|
+
if (record.schemaVersion !== 2) {
|
|
38
|
+
throw journalError("schemaVersion must be 2");
|
|
54
39
|
}
|
|
55
|
-
if (record.phase !== "prepared" &&
|
|
56
|
-
record.phase !== "applied" &&
|
|
57
|
-
!(record.schemaVersion === 2 && record.phase === "restoring")) {
|
|
40
|
+
if (record.phase !== "prepared" && record.phase !== "applied" && record.phase !== "restoring") {
|
|
58
41
|
throw journalError("phase must be prepared, applied, or restoring");
|
|
59
42
|
}
|
|
60
43
|
if (typeof record.ownerPid !== "number" ||
|
|
@@ -71,9 +54,6 @@ export function parseSystemProxyJournal(value) {
|
|
|
71
54
|
catch (err) {
|
|
72
55
|
throw journalError(errorMessage(err));
|
|
73
56
|
}
|
|
74
|
-
if (!journalSnapshotsHaveSameStructure(original, target)) {
|
|
75
|
-
throw journalError("original and target have different platform structures");
|
|
76
|
-
}
|
|
77
57
|
return {
|
|
78
58
|
schemaVersion: 2,
|
|
79
59
|
phase: record.phase,
|
|
@@ -101,47 +81,57 @@ export class SystemProxyManager {
|
|
|
101
81
|
backend;
|
|
102
82
|
operationLockFile;
|
|
103
83
|
operationQueue = Promise.resolve();
|
|
84
|
+
pendingWrites = 0;
|
|
104
85
|
inspectionGeneration = 0;
|
|
105
86
|
inspectionCache;
|
|
106
87
|
inspectionInFlight;
|
|
107
|
-
constructor(options = {}
|
|
108
|
-
if (typeof options !== "object" ||
|
|
109
|
-
options === null ||
|
|
110
|
-
Array.isArray(options) ||
|
|
111
|
-
unexpected.length > 0 ||
|
|
112
|
-
"systemProxyStateFile" in options) {
|
|
113
|
-
throw new Error("SystemProxyManager requires an options object with layout and backend fields");
|
|
114
|
-
}
|
|
88
|
+
constructor(options = {}) {
|
|
115
89
|
this.layout = options.layout ?? sashLayout();
|
|
116
90
|
this.backend = options.backend ?? createSystemProxyBackend();
|
|
117
91
|
if (!this.layout.systemProxyStateFile) {
|
|
118
92
|
throw new Error("System proxy journal requires a systemProxyStateFile path");
|
|
119
93
|
}
|
|
120
|
-
this.operationLockFile =
|
|
94
|
+
this.operationLockFile = this.layout.systemProxyLockFile;
|
|
121
95
|
}
|
|
122
96
|
apply(opts) {
|
|
97
|
+
this.pendingWrites += 1;
|
|
123
98
|
this.invalidateInspection();
|
|
124
99
|
return this.enqueue(async () => {
|
|
125
100
|
try {
|
|
126
101
|
await withStateLock(this.operationLockFile, { purpose: "apply system proxy", timeoutMs: 30_000 }, () => this.applyUnlocked(opts));
|
|
127
102
|
}
|
|
128
103
|
finally {
|
|
104
|
+
this.pendingWrites -= 1;
|
|
129
105
|
this.invalidateInspection();
|
|
130
106
|
}
|
|
131
107
|
});
|
|
132
108
|
}
|
|
133
109
|
release() {
|
|
110
|
+
this.pendingWrites += 1;
|
|
134
111
|
this.invalidateInspection();
|
|
135
112
|
return this.enqueue(async () => {
|
|
136
113
|
try {
|
|
137
114
|
await withStateLock(this.operationLockFile, { purpose: "restore system proxy", timeoutMs: 30_000 }, () => this.recoverUnlocked());
|
|
138
115
|
}
|
|
139
116
|
finally {
|
|
117
|
+
this.pendingWrites -= 1;
|
|
140
118
|
this.invalidateInspection();
|
|
141
119
|
}
|
|
142
120
|
});
|
|
143
121
|
}
|
|
144
122
|
inspect(fresh = false) {
|
|
123
|
+
if (this.pendingWrites > 0) {
|
|
124
|
+
return Promise.resolve({
|
|
125
|
+
applied: false,
|
|
126
|
+
appliedKnown: false,
|
|
127
|
+
stateKnown: false,
|
|
128
|
+
state: this.inspectionCache?.inspection.state ?? {
|
|
129
|
+
supported: this.backend.supported ?? isSystemProxySupported(),
|
|
130
|
+
enabled: false,
|
|
131
|
+
},
|
|
132
|
+
queryError: "System proxy change is in progress",
|
|
133
|
+
});
|
|
134
|
+
}
|
|
145
135
|
const generation = this.inspectionGeneration;
|
|
146
136
|
if (!fresh &&
|
|
147
137
|
this.inspectionCache?.generation === generation &&
|
|
@@ -268,6 +258,21 @@ export class SystemProxyManager {
|
|
|
268
258
|
};
|
|
269
259
|
}
|
|
270
260
|
async inspectUncached() {
|
|
261
|
+
if (this.backend.supported === false) {
|
|
262
|
+
return {
|
|
263
|
+
journalStable: true,
|
|
264
|
+
inspection: {
|
|
265
|
+
applied: false,
|
|
266
|
+
appliedKnown: true,
|
|
267
|
+
stateKnown: true,
|
|
268
|
+
state: {
|
|
269
|
+
supported: false,
|
|
270
|
+
enabled: false,
|
|
271
|
+
details: "System proxy integration is available on Windows only",
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
}
|
|
271
276
|
const first = await this.inspectAttempt();
|
|
272
277
|
return first.journalStable ? first : this.inspectAttempt();
|
|
273
278
|
}
|
|
@@ -371,9 +376,6 @@ export class SystemProxyManager {
|
|
|
371
376
|
}
|
|
372
377
|
const original = await this.captureCurrent();
|
|
373
378
|
const target = parseSystemProxySnapshot(this.backend.createTarget(original, opts));
|
|
374
|
-
if (!journalSnapshotsHaveSameStructure(original, target)) {
|
|
375
|
-
throw new Error("System proxy backend produced a target with a different platform structure");
|
|
376
|
-
}
|
|
377
379
|
const prepared = {
|
|
378
380
|
schemaVersion: 2,
|
|
379
381
|
phase: "prepared",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as Q,w as M,o as u,c as p,a as c,b as Z,e as o,I as m,f as J,u as a,t as s,v as R,g as i,h as x,s as T,P as W,n as y,F as B,r as N,i as D,j as F,k as X,l as Y,m as tt,E as et,p as h,q as _,x as at,y as A,z as H,A as st,B as ot,_ as nt}from"./index-
|
|
1
|
+
import{d as Q,w as M,o as u,c as p,a as c,b as Z,e as o,I as m,f as J,u as a,t as s,v as R,g as i,h as x,s as T,P as W,n as y,F as B,r as N,i as D,j as F,k as X,l as Y,m as tt,E as et,p as h,q as _,x as at,y as A,z as H,A as st,B as ot,_ as nt}from"./index-CBInDvdJ.js";import{P as lt}from"./PaginationFooter-cj1tcZej.js";const it={class:"connections-view"},ct={class:"search-box connection-search"},rt=["aria-label","placeholder"],ut={class:"connection-totals mono"},dt={class:"connections-control"},pt=["aria-label"],mt=["title"],vt=["title"],ht=["title"],_t=["title"],ft={class:"control-actions"},gt=["disabled"],bt={class:"connection-list"},yt={class:"connection-main"},wt=["title"],Ct={class:"connection-tags"},kt={class:"connection-tag tag-network"},Pt=["title"],xt=["title"],Tt={class:"connection-tag tag-time"},At={class:"connection-tag tag-traffic mono"},zt=["aria-label","title","onClick"],I=80,Bt=Q({__name:"ConnectionsView",setup(Dt){const w=h(""),v=h(1),d=h("time"),f=h(!0),r=h(!1),g=h([]);function L(){r.value||(g.value=[...T.connections]),r.value=!r.value}function C(e){d.value===e?f.value=!f.value:(d.value=e,f.value=!0)}function k(e){return{active:d.value===e,reverse:d.value===e&&!f.value}}const b=_(()=>r.value?g.value:T.connections);function O(e,n){const t=l=>!!l?.toLowerCase().includes(n);return t(e.metadata.host)||t(e.metadata.destinationIP)||t(e.metadata.sourceIP)||t(e.metadata.processPath)||t(e.metadata.network)||t(e.rule)||t(e.rulePayload)||e.chains.some(l=>t(l))}const P=_(()=>{const e=w.value.trim().toLowerCase(),n=e?b.value.filter(l=>O(l,e)):[...b.value],t=l=>d.value==="upload"?l.upload:d.value==="download"?l.download:d.value==="host"?z(l):l.start;return n.map(l=>({connection:l,key:t(l)})).sort((l,E)=>{const U=l.key<E.key?-1:l.key>E.key?1:0;return f.value?-U:U}).map(l=>l.connection)}),S=_(()=>Math.max(1,Math.ceil(P.value.length/I))),V=_(()=>(v.value-1)*I),q=_(()=>Math.min(V.value+I,P.value.length)),j=_(()=>P.value.slice(V.value,q.value));M(w,()=>{v.value=1}),M(S,e=>{v.value=Math.min(v.value,e)},{immediate:!0});function z(e){return e.metadata.host?e.metadata.host:`${e.metadata.destinationIP}:${e.metadata.destinationPort}`}function $(e){const n=e.metadata.processPath;return n?n.split(/[\\/]/).pop()??n:"-"}async function G(e){try{await at(e),r.value&&(g.value=g.value.filter(n=>n.id!==e)),A.success(s("toast.connClosed"))}catch(n){A.error(s("toast.failed",{msg:H(n)}))}}async function K(){const e=b.value.length;if(await st({title:s("connections.closeAll"),message:s("connections.closeAllConfirm",{n:e}),confirmText:s("common.confirm"),cancelText:s("common.cancel"),danger:!0}))try{await ot(),g.value=[],A.success(s("toast.connAllClosed"))}catch(t){A.error(s("toast.failed",{msg:H(t)}))}}return(e,n)=>(u(),p("div",it,[c(W,{title:a(s)("page.connections.title")},{default:Z(()=>[o("div",ct,[c(m,{name:"search",size:13}),J(o("input",{"onUpdate:modelValue":n[0]||(n[0]=t=>w.value=t),type:"search","aria-label":a(s)("connections.searchPlaceholder"),placeholder:a(s)("connections.searchPlaceholder")},null,8,rt),[[R,w.value]])]),o("div",ut,i(a(s)("connections.totalShort",{up:a(x)(a(T).connectionsUploadTotal),down:a(x)(a(T).connectionsDownloadTotal)})),1)]),_:1},8,["title"]),o("div",dt,[o("div",{class:"sort-labels",role:"toolbar","aria-label":a(s)("connections.colAction")},[o("button",{type:"button",class:y(["sort-label-btn",k("time")]),title:a(s)("connections.sortTime"),onClick:n[1]||(n[1]=t=>C("time"))},[c(m,{name:"timer",size:13}),o("span",null,i(a(s)("connections.sortTime")),1)],10,mt),o("button",{type:"button",class:y(["sort-label-btn",k("upload")]),title:a(s)("connections.sortUpload"),onClick:n[2]||(n[2]=t=>C("upload"))},[c(m,{name:"upload",size:13}),o("span",null,i(a(s)("connections.sortUpload")),1)],10,vt),o("button",{type:"button",class:y(["sort-label-btn",k("download")]),title:a(s)("connections.sortDownload"),onClick:n[3]||(n[3]=t=>C("download"))},[c(m,{name:"download",size:13}),o("span",null,i(a(s)("connections.sortDownload")),1)],10,ht),o("button",{type:"button",class:y(["sort-label-btn",k("host")]),title:a(s)("connections.sortHost"),onClick:n[4]||(n[4]=t=>C("host"))},[c(m,{name:"monitor",size:13}),o("span",null,i(a(s)("connections.sortHost")),1)],10,_t)],8,pt),o("div",ft,[o("button",{type:"button",class:y(["btn btn-sm btn-pause",{"btn-paused":r.value}]),onClick:L},[c(m,{name:r.value?"play":"pause",size:13},null,8,["name"]),o("span",null,i(r.value?a(s)("connections.resume"):a(s)("connections.pause")),1)],2),o("button",{type:"button",class:"btn btn-sm btn-danger",disabled:b.value.length===0,onClick:K},i(a(s)("connections.closeAll"))+" ("+i(b.value.length)+") ",9,gt)])]),o("div",bt,[(u(!0),p(B,null,N(j.value,t=>(u(),p("article",{key:t.id,class:"connection-row"},[o("div",yt,[o("div",{class:"connection-host mono",title:z(t)},i(z(t)),9,wt),o("div",Ct,[o("span",kt,i(t.metadata.network.toUpperCase()),1),$(t)!=="-"?(u(),p("span",{key:0,class:"connection-tag tag-process",title:t.metadata.processPath},i($(t)),9,Pt)):D("",!0),(u(!0),p(B,null,N(t.chains,l=>(u(),p("span",{key:l,class:"connection-tag tag-chain"},i(l),1))),128)),o("span",{class:"connection-tag tag-rule",title:t.rulePayload},[F(i(t.rule||"-"),1),t.rulePayload?(u(),p(B,{key:0},[F(","+i(t.rulePayload),1)],64)):D("",!0)],8,xt),o("span",Tt,i(a(X)(t.start,a(Y))),1),o("span",At," ↑"+i(a(x)(t.upload))+" ↓"+i(a(x)(t.download)),1)])]),o("button",{type:"button",class:"connection-close","aria-label":a(s)("connections.closeTitle"),title:a(s)("connections.closeTitle"),onClick:l=>G(t.id)},[c(m,{name:"x",size:18})],8,zt)]))),128)),P.value.length===0?(u(),tt(et,{key:0,icon:"swap",title:a(s)("connections.empty")},null,8,["title"])):D("",!0)]),c(lt,{page:v.value,"onUpdate:page":n[5]||(n[5]=t=>v.value=t),pages:S.value},null,8,["page","pages"])]))}}),Vt=nt(Bt,[["__scopeId","data-v-12653872"]]);export{Vt as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as A,w as D,s as i,C as I,D as N,o as c,c as u,a as b,b as U,e as n,I as w,f as L,u as a,t as s,v as q,F as C,r as k,g as d,G as z,H as x,P as R,i as V,n as S,q as B,p as v,J as G,_ as E}from"./index-
|
|
1
|
+
import{d as A,w as D,s as i,C as I,D as N,o as c,c as u,a as b,b as U,e as n,I as w,f as L,u as a,t as s,v as q,F as C,r as k,g as d,G as z,H as x,P as R,i as V,n as S,q as B,p as v,J as G,_ as E}from"./index-CBInDvdJ.js";const J={class:"logs-view"},Q={class:"search-box logs-search"},$=["aria-label","placeholder"],j=["aria-label"],K=["value"],O=["disabled"],W=["aria-pressed"],X=["aria-label"],Y={key:0,class:"log-empty text-muted"},Z={class:"log-payload"},ee={key:0,class:"log-time mono"},le=A({__name:"LogsView",setup(ae){const F=["all","info","warning","error","debug"],T=B(()=>{const l={rule:s("overview.modeRule"),global:s("overview.modeGlobal"),direct:s("overview.modeDirect")};return s("logs.modeLabel",{mode:l[i.mode]??i.mode})}),m=v("all"),g=v(""),t=v(!1),f=v(null),p=v(!0);let r=null,_=!1;const y=B(()=>{const l=g.value.trim().toLowerCase();return i.logs.filter(o=>(m.value==="all"||o.type.toLowerCase()===m.value)&&(!l||o.payload.toLowerCase().includes(l)))});function H(l){const o=l.toLowerCase();return o==="error"?"alert":o==="warning"?"info":o==="debug"?"terminal":"check-circle"}function M(){const l=f.value;l&&(p.value=l.scrollHeight-l.scrollTop-l.clientHeight<40)}async function h(){await G(),!(_||t.value||!p.value)&&(r!==null&&cancelAnimationFrame(r),r=requestAnimationFrame(()=>{r=null;const l=f.value;l&&!_&&!t.value&&p.value&&(l.scrollTop=l.scrollHeight)}))}function P(){t.value=!t.value,t.value||h()}return D(()=>i.logs.at(-1)?.id,()=>{!t.value&&p.value&&h()}),I(()=>{h()}),N(()=>{_=!0,r!==null&&cancelAnimationFrame(r)}),(l,o)=>(c(),u("div",J,[b(R,{title:a(s)("page.logs.title"),desc:T.value},{default:U(()=>[n("div",Q,[b(w,{name:"search",size:13}),L(n("input",{"onUpdate:modelValue":o[0]||(o[0]=e=>g.value=e),type:"search","aria-label":a(s)("logs.searchPlaceholder"),placeholder:a(s)("logs.searchPlaceholder")},null,8,$),[[q,g.value]])]),L(n("select",{"onUpdate:modelValue":o[1]||(o[1]=e=>m.value=e),class:"input input-sm level-select","aria-label":a(s)("logs.levelLabel")},[(c(),u(C,null,k(F,e=>n("option",{key:e,value:e},d(e==="all"?a(s)("logs.levelAll"):e.toUpperCase()),9,K)),64))],8,j),[[z,m.value]]),n("button",{type:"button",class:"btn btn-sm log-clear",disabled:a(i).logs.length===0,onClick:o[2]||(o[2]=(...e)=>a(x)&&a(x)(...e))},d(a(s)("common.clear")),9,O),n("button",{type:"button",class:"btn btn-sm log-pause","aria-pressed":t.value,onClick:P},d(t.value?a(s)("logs.resume"):a(s)("logs.pause")),9,W)]),_:1},8,["title","desc"]),n("div",{ref_key:"paneRef",ref:f,class:"log-pane",role:"log",tabindex:"0","aria-live":"off","aria-atomic":"false","aria-label":a(s)("page.logs.title"),onScroll:M},[y.value.length===0?(c(),u("div",Y,d(a(i).logs.length===0?a(s)("logs.listening"):a(s)("logs.empty")),1)):V("",!0),(c(!0),u(C,null,k(y.value,e=>(c(),u("div",{key:e.id,class:S(["log-line",`lv-${e.type.toLowerCase()}`])},[b(w,{name:H(e.type),size:13,class:"log-icon"},null,8,["name"]),n("span",Z,d(e.payload),1),e.time?(c(),u("span",ee,d(e.time),1)):V("",!0)],2))),128))],40,X)]))}}),oe=E(le,[["__scopeId","data-v-a97e5fe8"]]);export{oe as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as c,
|
|
1
|
+
import{d as c,a6 as r,o as l,c as p,e as o,g as s,u as n,t as i,i as m,a7 as u,_ as g}from"./index-CBInDvdJ.js";const b={key:0,class:"pagination-footer"},_={class:"pagination-summary"},v={class:"pagination-actions"},f=["disabled"],y=["disabled"],k=c({__name:"PaginationFooter",props:u({pages:{}},{page:{required:!0},pageModifiers:{}}),emits:["update:page"],setup(t){const e=r(t,"page");return(x,a)=>t.pages>1?(l(),p("footer",b,[o("span",_,s(n(i)("common.pageSummary",{page:e.value,total:t.pages})),1),o("div",v,[o("button",{type:"button",class:"btn btn-secondary btn-sm",disabled:e.value===1,onClick:a[0]||(a[0]=d=>e.value-=1)},s(n(i)("common.previous")),9,f),o("button",{type:"button",class:"btn btn-secondary btn-sm",disabled:e.value===t.pages,onClick:a[1]||(a[1]=d=>e.value+=1)},s(n(i)("common.next")),9,y)])])):m("",!0)}}),B=g(k,[["__scopeId","data-v-c2140dca"]]);export{B as P};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.editor-overlay[data-v-be7c4f1f]{position:fixed;inset:0;z-index:var(--z-dialog);display:flex;padding:26px;background:var(--bg-scrim)}.editor-dialog[data-v-be7c4f1f]{display:flex;width:100%;min-height:0;flex:1;flex-direction:column;overflow:hidden;background:var(--bg-elevated);border-radius:var(--radius-md);box-shadow:var(--shadow-pop)}.editor-dialog-constrained[data-v-be7c4f1f]{max-width:720px;max-height:100%;margin:auto;flex:0 1 auto}.editor-head[data-v-be7c4f1f]{display:flex;min-height:46px;align-items:center;gap:12px;padding:6px 10px 6px 16px;border-bottom:1px solid var(--border)}.editor-name[data-v-be7c4f1f]{min-width:0;overflow:hidden;color:var(--text-primary);font-size:16px;font-weight:600;text-overflow:ellipsis;white-space:nowrap}.editor-hint[data-v-be7c4f1f]{min-width:0;flex:1;overflow:hidden;color:var(--warning);font-size:14px;text-overflow:ellipsis;white-space:nowrap}.editor-actions[data-v-be7c4f1f]{display:flex;flex-shrink:0;gap:8px;margin-left:auto}.editor-error[data-v-be7c4f1f]{padding:18px 20px;color:var(--danger);font-size:16px}.editor-host[data-v-be7c4f1f]{position:relative;min-height:0;flex:1;overflow:hidden}.editor-host-constrained[data-v-be7c4f1f]{min-height:320px}.editor-loading[data-v-be7c4f1f]{position:absolute;top:12px;left:16px;color:var(--text-muted);font-size:16px}.editor-host[data-v-be7c4f1f] .cm-editor{height:100%;font-size:16px}.editor-host[data-v-be7c4f1f] .cm-editor .cm-scroller{font-family:var(--font-mono)}.editor-host[data-v-be7c4f1f] .cm-editor.cm-focused{outline:none}@media(max-width:640px){.editor-overlay[data-v-be7c4f1f]{padding:0}.editor-dialog[data-v-be7c4f1f]{border-radius:0}.editor-dialog-constrained[data-v-be7c4f1f]{max-width:none}.editor-hint[data-v-be7c4f1f]{display:none}}
|