@jobshimo/browser-link 0.40.0 → 0.42.0
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/README.md +27 -12
- package/dist/admin/actions.d.ts +57 -0
- package/dist/admin/actions.js +163 -0
- package/dist/admin/actions.js.map +1 -0
- package/dist/admin/descriptor.d.ts +65 -0
- package/dist/admin/descriptor.js +205 -0
- package/dist/admin/descriptor.js.map +1 -0
- package/dist/admin/i18n.d.ts +90 -0
- package/dist/admin/i18n.js +203 -0
- package/dist/admin/i18n.js.map +1 -0
- package/dist/admin/primary.d.ts +21 -0
- package/dist/admin/primary.js +56 -0
- package/dist/admin/primary.js.map +1 -0
- package/dist/admin/sources.d.ts +22 -0
- package/dist/admin/sources.js +82 -0
- package/dist/admin/sources.js.map +1 -0
- package/dist/bridge/dispatch.js +17 -7
- package/dist/bridge/dispatch.js.map +1 -1
- package/dist/bridge/ws-bridge.d.ts +65 -3
- package/dist/bridge/ws-bridge.js +165 -7
- package/dist/bridge/ws-bridge.js.map +1 -1
- package/dist/cli.js +6 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/doctor.d.ts +24 -0
- package/dist/commands/doctor.js +62 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/free-port.d.ts +40 -1
- package/dist/commands/free-port.js +72 -7
- package/dist/commands/free-port.js.map +1 -1
- package/dist/extension/admin-view.d.ts +95 -0
- package/dist/extension/admin-view.js +164 -0
- package/dist/extension/admin-view.js.map +1 -0
- package/dist/extension/background.js +176 -8
- package/dist/extension/background.js.map +1 -1
- package/dist/extension/manifest.json +1 -1
- package/dist/extension/popup.html +113 -0
- package/dist/extension/popup.js +282 -1
- package/dist/extension/popup.js.map +1 -1
- package/dist/extension/repair-policy.d.ts +60 -0
- package/dist/extension/repair-policy.js +79 -0
- package/dist/extension/repair-policy.js.map +1 -0
- package/dist/extension/version-status.d.ts +44 -0
- package/dist/extension/version-status.js +60 -0
- package/dist/extension/version-status.js.map +1 -0
- package/dist/lifecycle/election.d.ts +98 -0
- package/dist/lifecycle/election.js +187 -0
- package/dist/lifecycle/election.js.map +1 -0
- package/dist/lifecycle/processes.d.ts +67 -0
- package/dist/lifecycle/processes.js +239 -0
- package/dist/lifecycle/processes.js.map +1 -0
- package/dist/lifecycle/repair.d.ts +48 -0
- package/dist/lifecycle/repair.js +67 -0
- package/dist/lifecycle/repair.js.map +1 -0
- package/dist/lifecycle/version-endpoint.d.ts +16 -0
- package/dist/lifecycle/version-endpoint.js +50 -0
- package/dist/lifecycle/version-endpoint.js.map +1 -0
- package/dist/manual/topics.js +1 -1
- package/dist/manual/topics.js.map +1 -1
- package/dist/messages.d.ts +115 -2
- package/dist/server.js +104 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/browser-dispatch.d.ts +8 -0
- package/dist/tools/browser-dispatch.js +15 -1
- package/dist/tools/browser-dispatch.js.map +1 -1
- package/dist/ui/app.d.ts +4 -1
- package/dist/ui/app.js +55 -42
- package/dist/ui/app.js.map +1 -1
- package/dist/ui/screens/free-port.js +4 -2
- package/dist/ui/screens/free-port.js.map +1 -1
- package/dist/ui/screens/index.d.ts +1 -0
- package/dist/ui/screens/index.js +1 -0
- package/dist/ui/screens/index.js.map +1 -1
- package/dist/ui/screens/menu.d.ts +11 -1
- package/dist/ui/screens/menu.js +12 -4
- package/dist/ui/screens/menu.js.map +1 -1
- package/dist/ui/screens/status.d.ts +19 -0
- package/dist/ui/screens/status.js +67 -0
- package/dist/ui/screens/status.js.map +1 -0
- package/dist/version.d.ts +8 -0
- package/dist/version.js +16 -0
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Language } from './welcome.js';
|
|
2
|
+
import { type ProcessEntry } from '../lifecycle/processes.js';
|
|
2
3
|
export interface FreePortResult {
|
|
3
4
|
/** True when the port was free (nothing to do) OR the owning process was killed. */
|
|
4
5
|
ok: boolean;
|
|
@@ -8,7 +9,36 @@ export interface FreePortResult {
|
|
|
8
9
|
imageName: string | null;
|
|
9
10
|
/** Human-readable message in the requested language. */
|
|
10
11
|
message: string;
|
|
12
|
+
/** Since 0.41.0: every browser-link process this run tried to stop (the
|
|
13
|
+
* 17529 owner, the 17530 owner and every other live bridge), in kill
|
|
14
|
+
* order. Absent when there was none, so the "already free" result keeps
|
|
15
|
+
* its exact previous shape. */
|
|
16
|
+
processes?: StoppedProcess[];
|
|
11
17
|
}
|
|
18
|
+
export interface StoppedProcess {
|
|
19
|
+
pid: number;
|
|
20
|
+
/** Short display form, e.g. `node browser-link start`. */
|
|
21
|
+
command: string;
|
|
22
|
+
stopped: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Best-effort lookup of the PID owning the WS port, cross-platform.
|
|
26
|
+
* Returns null when nothing is listening on the port, when the OS tools
|
|
27
|
+
* needed to find the owner are missing, or when parsing fails.
|
|
28
|
+
*
|
|
29
|
+
* We don't shell out via a string command — `execFileSync` with an argv
|
|
30
|
+
* array avoids any quoting / injection surprises.
|
|
31
|
+
*/
|
|
32
|
+
export declare function findPidOnPort(port: number): number | null;
|
|
33
|
+
/**
|
|
34
|
+
* Return the image / executable name of a PID, or null when the lookup
|
|
35
|
+
* fails. We use this as a safety check before killing: we will only kill
|
|
36
|
+
* processes whose image name starts with "node" — refuse to nuke anything
|
|
37
|
+
* else that happens to share the port (some other dev server, malware,
|
|
38
|
+
* a misconfigured tool, etc.).
|
|
39
|
+
*/
|
|
40
|
+
export declare function imageNameOf(pid: number): string | null;
|
|
41
|
+
export declare function isNodeImage(image: string | null): boolean;
|
|
12
42
|
/**
|
|
13
43
|
* Find the process listening on WS_PORT and try to stop it.
|
|
14
44
|
*
|
|
@@ -17,5 +47,14 @@ export interface FreePortResult {
|
|
|
17
47
|
* This stops a stray browser-link from blocking the next MCP client
|
|
18
48
|
* without ever risking killing some unrelated user process that happens
|
|
19
49
|
* to share the port.
|
|
50
|
+
*
|
|
51
|
+
* Since 0.41.0 it then stops every OTHER live browser-link bridge too: the
|
|
52
|
+
* 17530 (IPC) owner when it is a node process, and every process whose
|
|
53
|
+
* command line runs this package with no subcommand or `start` (see
|
|
54
|
+
* `lifecycle/processes.ts`; never this process, its ancestors, or short
|
|
55
|
+
* commands such as `doctor`). Each one gets a line under the original
|
|
56
|
+
* message; with nothing else running, the result is exactly what it was.
|
|
20
57
|
*/
|
|
21
|
-
export declare function runFreePort(language?: Language
|
|
58
|
+
export declare function runFreePort(language?: Language, deps?: {
|
|
59
|
+
listBridgeProcesses?: () => ProcessEntry[];
|
|
60
|
+
}): FreePortResult;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { execFileSync } from 'node:child_process';
|
|
2
2
|
import { platform } from 'node:os';
|
|
3
|
+
import { IPC_PORT } from '../bridge/protocol.js';
|
|
4
|
+
import { listBridgeProcesses, shortCommand } from '../lifecycle/processes.js';
|
|
3
5
|
const WS_HOST = '127.0.0.1';
|
|
4
6
|
const WS_PORT = 17529;
|
|
5
7
|
/**
|
|
@@ -10,7 +12,7 @@ const WS_PORT = 17529;
|
|
|
10
12
|
* We don't shell out via a string command — `execFileSync` with an argv
|
|
11
13
|
* array avoids any quoting / injection surprises.
|
|
12
14
|
*/
|
|
13
|
-
function findPidOnPort(port) {
|
|
15
|
+
export function findPidOnPort(port) {
|
|
14
16
|
try {
|
|
15
17
|
if (platform() === 'win32') {
|
|
16
18
|
// netstat -ano -p TCP produces lines like:
|
|
@@ -50,7 +52,7 @@ function findPidOnPort(port) {
|
|
|
50
52
|
* else that happens to share the port (some other dev server, malware,
|
|
51
53
|
* a misconfigured tool, etc.).
|
|
52
54
|
*/
|
|
53
|
-
function imageNameOf(pid) {
|
|
55
|
+
export function imageNameOf(pid) {
|
|
54
56
|
try {
|
|
55
57
|
if (platform() === 'win32') {
|
|
56
58
|
// tasklist /FI "PID eq 13212" /FO CSV /NH produces:
|
|
@@ -78,7 +80,7 @@ function imageNameOf(pid) {
|
|
|
78
80
|
return null;
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
|
-
function isNodeImage(image) {
|
|
83
|
+
export function isNodeImage(image) {
|
|
82
84
|
if (!image)
|
|
83
85
|
return false;
|
|
84
86
|
const lc = image.toLowerCase();
|
|
@@ -108,6 +110,9 @@ const I18N = {
|
|
|
108
110
|
`Refusing to kill it — close that process yourself if you know what it is.`,
|
|
109
111
|
unknownOwner: (pid) => `✗ Port ${WS_HOST}:${WS_PORT} is held by PID ${pid}, but we could not identify the process. ` +
|
|
110
112
|
`Refusing to kill it. Close it manually with: taskkill /F /PID ${pid} (Windows) or kill ${pid} (Unix).`,
|
|
113
|
+
othersHeader: 'Other browser-link processes:',
|
|
114
|
+
stopped: '✓ stopped',
|
|
115
|
+
stopFailed: '✗ could not stop',
|
|
111
116
|
},
|
|
112
117
|
es: {
|
|
113
118
|
alreadyFree: `El puerto ${WS_HOST}:${WS_PORT} ya está libre — no hay nada que parar.`,
|
|
@@ -117,6 +122,9 @@ const I18N = {
|
|
|
117
122
|
`Por seguridad no se mata — cerralo a mano si sabés qué es.`,
|
|
118
123
|
unknownOwner: (pid) => `✗ El puerto ${WS_HOST}:${WS_PORT} lo tiene el PID ${pid}, pero no pudimos identificar el proceso. ` +
|
|
119
124
|
`Por seguridad no se mata. Cerralo a mano con: taskkill /F /PID ${pid} (Windows) o kill ${pid} (Unix).`,
|
|
125
|
+
othersHeader: 'Otros procesos de browser-link:',
|
|
126
|
+
stopped: '✓ detenido',
|
|
127
|
+
stopFailed: '✗ no se pudo detener',
|
|
120
128
|
},
|
|
121
129
|
};
|
|
122
130
|
/**
|
|
@@ -127,19 +135,75 @@ const I18N = {
|
|
|
127
135
|
* This stops a stray browser-link from blocking the next MCP client
|
|
128
136
|
* without ever risking killing some unrelated user process that happens
|
|
129
137
|
* to share the port.
|
|
138
|
+
*
|
|
139
|
+
* Since 0.41.0 it then stops every OTHER live browser-link bridge too: the
|
|
140
|
+
* 17530 (IPC) owner when it is a node process, and every process whose
|
|
141
|
+
* command line runs this package with no subcommand or `start` (see
|
|
142
|
+
* `lifecycle/processes.ts`; never this process, its ancestors, or short
|
|
143
|
+
* commands such as `doctor`). Each one gets a line under the original
|
|
144
|
+
* message; with nothing else running, the result is exactly what it was.
|
|
130
145
|
*/
|
|
131
|
-
export function runFreePort(language = 'en') {
|
|
146
|
+
export function runFreePort(language = 'en', deps = {}) {
|
|
132
147
|
const t = I18N[language];
|
|
148
|
+
const primary = stopPortOwner(t);
|
|
149
|
+
const list = (deps.listBridgeProcesses ?? (() => listBridgeProcesses()))();
|
|
150
|
+
const commandOf = (pid, fallback) => {
|
|
151
|
+
const entry = list.find((p) => p.pid === pid);
|
|
152
|
+
return entry ? shortCommand(entry.command) : (fallback ?? '?');
|
|
153
|
+
};
|
|
154
|
+
const processes = [];
|
|
155
|
+
if (primary.pid !== null && primary.attempted) {
|
|
156
|
+
processes.push({
|
|
157
|
+
pid: primary.pid,
|
|
158
|
+
command: commandOf(primary.pid, primary.imageName),
|
|
159
|
+
stopped: primary.ok,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// Everything else: the IPC owner (node only, same safety rule) and every
|
|
163
|
+
// other bridge, each once, never the 17529 owner a second time.
|
|
164
|
+
const seen = new Set(primary.pid !== null ? [primary.pid] : []);
|
|
165
|
+
const others = [];
|
|
166
|
+
const ipcPid = findPidOnPort(IPC_PORT);
|
|
167
|
+
if (ipcPid !== null && !seen.has(ipcPid) && isNodeImage(imageNameOf(ipcPid))) {
|
|
168
|
+
seen.add(ipcPid);
|
|
169
|
+
others.push({ pid: ipcPid, command: commandOf(ipcPid, 'node') });
|
|
170
|
+
}
|
|
171
|
+
for (const p of list) {
|
|
172
|
+
if (seen.has(p.pid))
|
|
173
|
+
continue;
|
|
174
|
+
seen.add(p.pid);
|
|
175
|
+
others.push({ pid: p.pid, command: shortCommand(p.command) });
|
|
176
|
+
}
|
|
177
|
+
const lines = [primary.message];
|
|
178
|
+
if (others.length > 0)
|
|
179
|
+
lines.push(t.othersHeader);
|
|
180
|
+
let allStopped = true;
|
|
181
|
+
for (const o of others) {
|
|
182
|
+
const stopped = killByPid(o.pid);
|
|
183
|
+
allStopped &&= stopped;
|
|
184
|
+
processes.push({ pid: o.pid, command: o.command, stopped });
|
|
185
|
+
lines.push(` PID ${o.pid} ${o.command} ${stopped ? t.stopped : t.stopFailed}`);
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
ok: primary.ok && allStopped,
|
|
189
|
+
pid: primary.pid,
|
|
190
|
+
imageName: primary.imageName,
|
|
191
|
+
message: lines.join('\n'),
|
|
192
|
+
...(processes.length > 0 ? { processes } : {}),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/** The original 17529 rule, unchanged: only a node owner is killed. */
|
|
196
|
+
function stopPortOwner(t) {
|
|
133
197
|
const pid = findPidOnPort(WS_PORT);
|
|
134
198
|
if (pid == null) {
|
|
135
|
-
return { ok: true, pid: null, imageName: null, message: t.alreadyFree };
|
|
199
|
+
return { ok: true, pid: null, imageName: null, message: t.alreadyFree, attempted: false };
|
|
136
200
|
}
|
|
137
201
|
const image = imageNameOf(pid);
|
|
138
202
|
if (image == null) {
|
|
139
|
-
return { ok: false, pid, imageName: null, message: t.unknownOwner(pid) };
|
|
203
|
+
return { ok: false, pid, imageName: null, message: t.unknownOwner(pid), attempted: false };
|
|
140
204
|
}
|
|
141
205
|
if (!isNodeImage(image)) {
|
|
142
|
-
return { ok: false, pid, imageName: image, message: t.notNode(pid, image) };
|
|
206
|
+
return { ok: false, pid, imageName: image, message: t.notNode(pid, image), attempted: false };
|
|
143
207
|
}
|
|
144
208
|
const killed = killByPid(pid);
|
|
145
209
|
return {
|
|
@@ -147,6 +211,7 @@ export function runFreePort(language = 'en') {
|
|
|
147
211
|
pid,
|
|
148
212
|
imageName: image,
|
|
149
213
|
message: killed ? t.killed(pid) : t.killFailed(pid),
|
|
214
|
+
attempted: true,
|
|
150
215
|
};
|
|
151
216
|
}
|
|
152
217
|
//# sourceMappingURL=free-port.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"free-port.js","sourceRoot":"","sources":["../../src/commands/free-port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"free-port.js","sourceRoot":"","sources":["../../src/commands/free-port.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render model for the popup's Admin section.
|
|
3
|
+
*
|
|
4
|
+
* The server describes its administration state and actions as data, with
|
|
5
|
+
* every label already localised (`AdminState`). This module turns that data
|
|
6
|
+
* into flat view rows the popup can render without knowing what any item
|
|
7
|
+
* means, and owns the confirm flow for disk-writing actions as a tiny state
|
|
8
|
+
* machine. Pure: no DOM, no chrome.* — so it is tested, unlike popup.ts.
|
|
9
|
+
*/
|
|
10
|
+
import type { AdminActionResult, AdminItemKind, AdminOption, AdminSection, AdminState, AdminUiStrings } from '@browser-link/shared';
|
|
11
|
+
/** Used when the server sent no `ui` block, or when no server answered at all
|
|
12
|
+
* (no tab connected), so the popup still has words to show. */
|
|
13
|
+
export declare const FALLBACK_ADMIN_UI: AdminUiStrings;
|
|
14
|
+
export type AdminControl = 'none' | 'toggle' | 'select' | 'button' | 'link';
|
|
15
|
+
export interface AdminRow {
|
|
16
|
+
sectionId: AdminSection['id'];
|
|
17
|
+
sectionTitle: string;
|
|
18
|
+
itemId: string;
|
|
19
|
+
kind: AdminItemKind;
|
|
20
|
+
label: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
/** Human-readable current value; empty for buttons. */
|
|
23
|
+
valueText: string;
|
|
24
|
+
control: AdminControl;
|
|
25
|
+
/** Toggle only: the current state. */
|
|
26
|
+
checked?: boolean;
|
|
27
|
+
/** Select only: the current option value. */
|
|
28
|
+
selected?: string;
|
|
29
|
+
options?: AdminOption[];
|
|
30
|
+
/** Link only: an http(s) URL, never anything else. */
|
|
31
|
+
href?: string;
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
hint?: string;
|
|
34
|
+
requiresRestart?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/** What an admin request carries, minus the wire envelope. */
|
|
37
|
+
export interface AdminRequest {
|
|
38
|
+
id: string;
|
|
39
|
+
value?: string | number | boolean;
|
|
40
|
+
confirm?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/** Flatten the server state into rows, section then item order. A malformed
|
|
43
|
+
* state yields no rows: the popup shows an empty section, never a crash. */
|
|
44
|
+
export declare function buildAdminRows(state: AdminState | null | undefined): AdminRow[];
|
|
45
|
+
/** The server's UI strings, or the English fallback. */
|
|
46
|
+
export declare function adminUi(state: AdminState | null | undefined): AdminUiStrings;
|
|
47
|
+
/** `not-connected` is the background's own code for "no open socket"; it
|
|
48
|
+
* reads as the server's (or fallback) sentence. Anything else is shown as is. */
|
|
49
|
+
export declare function describeAdminError(error: string, ui: AdminUiStrings): string;
|
|
50
|
+
export type AdminNextAction = {
|
|
51
|
+
type: 'confirm';
|
|
52
|
+
preview: string;
|
|
53
|
+
confirmLabel: string;
|
|
54
|
+
cancelLabel: string;
|
|
55
|
+
resend: AdminRequest & {
|
|
56
|
+
confirm: true;
|
|
57
|
+
};
|
|
58
|
+
} | {
|
|
59
|
+
type: 'applied';
|
|
60
|
+
message: string;
|
|
61
|
+
output?: string[];
|
|
62
|
+
refresh: true;
|
|
63
|
+
} | {
|
|
64
|
+
type: 'error';
|
|
65
|
+
message: string;
|
|
66
|
+
};
|
|
67
|
+
/** Decide what the popup does with one action result. */
|
|
68
|
+
export declare function nextAction(result: AdminActionResult, request: AdminRequest, ui: AdminUiStrings): AdminNextAction;
|
|
69
|
+
export type ConfirmState = {
|
|
70
|
+
phase: 'idle';
|
|
71
|
+
} | {
|
|
72
|
+
phase: 'confirming';
|
|
73
|
+
preview: string;
|
|
74
|
+
pendingRequest: AdminRequest & {
|
|
75
|
+
confirm: true;
|
|
76
|
+
};
|
|
77
|
+
} | {
|
|
78
|
+
phase: 'applied';
|
|
79
|
+
message: string;
|
|
80
|
+
output?: string[];
|
|
81
|
+
} | {
|
|
82
|
+
phase: 'error';
|
|
83
|
+
message: string;
|
|
84
|
+
};
|
|
85
|
+
export type ConfirmEvent = {
|
|
86
|
+
type: 'result';
|
|
87
|
+
request: AdminRequest;
|
|
88
|
+
result: AdminActionResult;
|
|
89
|
+
ui: AdminUiStrings;
|
|
90
|
+
} | {
|
|
91
|
+
type: 'cancel';
|
|
92
|
+
};
|
|
93
|
+
export declare function initialConfirmState(): ConfirmState;
|
|
94
|
+
/** idle → confirming(preview, pendingRequest) → applied | error; cancel → idle. */
|
|
95
|
+
export declare function reduceConfirm(_state: ConfirmState, event: ConfirmEvent): ConfirmState;
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
/** Used when the server sent no `ui` block, or when no server answered at all
|
|
2
|
+
* (no tab connected), so the popup still has words to show. */
|
|
3
|
+
export const FALLBACK_ADMIN_UI = {
|
|
4
|
+
language: 'en',
|
|
5
|
+
confirm: 'Confirm',
|
|
6
|
+
cancel: 'Cancel',
|
|
7
|
+
apply: 'Apply',
|
|
8
|
+
notConnected: 'Connect a tab to administer the server',
|
|
9
|
+
restartRequired: 'Restart the server to apply this change',
|
|
10
|
+
changed: 'Changed',
|
|
11
|
+
};
|
|
12
|
+
const EMPTY_VALUE = '—';
|
|
13
|
+
function stringifyValue(value) {
|
|
14
|
+
if (value === undefined || value === null || value === '')
|
|
15
|
+
return EMPTY_VALUE;
|
|
16
|
+
if (typeof value === 'boolean')
|
|
17
|
+
return value ? 'on' : 'off';
|
|
18
|
+
return String(value);
|
|
19
|
+
}
|
|
20
|
+
function isHttpUrl(value) {
|
|
21
|
+
if (typeof value !== 'string')
|
|
22
|
+
return false;
|
|
23
|
+
try {
|
|
24
|
+
const url = new URL(value);
|
|
25
|
+
return url.protocol === 'https:' || url.protocol === 'http:';
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function rowFor(section, item) {
|
|
32
|
+
const row = {
|
|
33
|
+
sectionId: section.id,
|
|
34
|
+
sectionTitle: section.title,
|
|
35
|
+
itemId: item.id,
|
|
36
|
+
kind: item.kind,
|
|
37
|
+
label: item.label,
|
|
38
|
+
valueText: stringifyValue(item.value),
|
|
39
|
+
control: 'none',
|
|
40
|
+
};
|
|
41
|
+
if (item.description !== undefined)
|
|
42
|
+
row.description = item.description;
|
|
43
|
+
switch (item.kind) {
|
|
44
|
+
case 'toggle': {
|
|
45
|
+
row.control = 'toggle';
|
|
46
|
+
if (typeof item.value === 'boolean') {
|
|
47
|
+
row.checked = item.value;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
row.checked = false;
|
|
51
|
+
row.disabled = true;
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
case 'select': {
|
|
56
|
+
row.control = 'select';
|
|
57
|
+
const options = Array.isArray(item.options) ? item.options : [];
|
|
58
|
+
row.options = options;
|
|
59
|
+
const current = item.value === undefined || item.value === null ? '' : String(item.value);
|
|
60
|
+
row.selected = current;
|
|
61
|
+
const match = options.find((o) => o.value === current);
|
|
62
|
+
if (match)
|
|
63
|
+
row.valueText = match.label;
|
|
64
|
+
if (options.length === 0)
|
|
65
|
+
row.disabled = true;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case 'button': {
|
|
69
|
+
row.control = 'button';
|
|
70
|
+
row.valueText = '';
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
case 'link': {
|
|
74
|
+
// Only http(s) becomes clickable: the URL comes off a socket, and a
|
|
75
|
+
// `javascript:` href in an extension page is not something to render.
|
|
76
|
+
if (isHttpUrl(item.value)) {
|
|
77
|
+
row.control = 'link';
|
|
78
|
+
row.href = item.value;
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
default:
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
if (item.hint !== undefined)
|
|
86
|
+
row.hint = item.hint;
|
|
87
|
+
if (item.requiresRestart === true)
|
|
88
|
+
row.requiresRestart = true;
|
|
89
|
+
return row;
|
|
90
|
+
}
|
|
91
|
+
/** Flatten the server state into rows, section then item order. A malformed
|
|
92
|
+
* state yields no rows: the popup shows an empty section, never a crash. */
|
|
93
|
+
export function buildAdminRows(state) {
|
|
94
|
+
if (!state || !Array.isArray(state.sections))
|
|
95
|
+
return [];
|
|
96
|
+
const rows = [];
|
|
97
|
+
// The state arrives off a socket as JSON: entries are typed loosely here so
|
|
98
|
+
// the guards below are checks the compiler keeps, not dead code.
|
|
99
|
+
const sections = state.sections;
|
|
100
|
+
for (const section of sections) {
|
|
101
|
+
if (!section || !Array.isArray(section.items))
|
|
102
|
+
continue;
|
|
103
|
+
const items = section.items;
|
|
104
|
+
for (const item of items) {
|
|
105
|
+
if (!item || typeof item.id !== 'string')
|
|
106
|
+
continue;
|
|
107
|
+
rows.push(rowFor(section, item));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return rows;
|
|
111
|
+
}
|
|
112
|
+
/** The server's UI strings, or the English fallback. */
|
|
113
|
+
export function adminUi(state) {
|
|
114
|
+
return state?.ui ?? FALLBACK_ADMIN_UI;
|
|
115
|
+
}
|
|
116
|
+
/** `not-connected` is the background's own code for "no open socket"; it
|
|
117
|
+
* reads as the server's (or fallback) sentence. Anything else is shown as is. */
|
|
118
|
+
export function describeAdminError(error, ui) {
|
|
119
|
+
return error === 'not-connected' ? ui.notConnected : error;
|
|
120
|
+
}
|
|
121
|
+
/** Decide what the popup does with one action result. */
|
|
122
|
+
export function nextAction(result, request, ui) {
|
|
123
|
+
if (!result.ok)
|
|
124
|
+
return { type: 'error', message: describeAdminError(result.error, ui) };
|
|
125
|
+
if (!result.applied) {
|
|
126
|
+
const resend = { id: request.id, confirm: true };
|
|
127
|
+
if (request.value !== undefined)
|
|
128
|
+
resend.value = request.value;
|
|
129
|
+
return {
|
|
130
|
+
type: 'confirm',
|
|
131
|
+
preview: result.preview,
|
|
132
|
+
confirmLabel: ui.confirm,
|
|
133
|
+
cancelLabel: ui.cancel,
|
|
134
|
+
resend,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
const applied = {
|
|
138
|
+
type: 'applied',
|
|
139
|
+
message: result.requiresRestart === true ? ui.restartRequired : ui.changed,
|
|
140
|
+
refresh: true,
|
|
141
|
+
};
|
|
142
|
+
if (Array.isArray(result.output))
|
|
143
|
+
applied.output = result.output;
|
|
144
|
+
return applied;
|
|
145
|
+
}
|
|
146
|
+
export function initialConfirmState() {
|
|
147
|
+
return { phase: 'idle' };
|
|
148
|
+
}
|
|
149
|
+
/** idle → confirming(preview, pendingRequest) → applied | error; cancel → idle. */
|
|
150
|
+
export function reduceConfirm(_state, event) {
|
|
151
|
+
if (event.type === 'cancel')
|
|
152
|
+
return { phase: 'idle' };
|
|
153
|
+
const action = nextAction(event.result, event.request, event.ui);
|
|
154
|
+
if (action.type === 'confirm') {
|
|
155
|
+
return { phase: 'confirming', preview: action.preview, pendingRequest: action.resend };
|
|
156
|
+
}
|
|
157
|
+
if (action.type === 'error')
|
|
158
|
+
return { phase: 'error', message: action.message };
|
|
159
|
+
const applied = { phase: 'applied', message: action.message };
|
|
160
|
+
if (action.output)
|
|
161
|
+
applied.output = action.output;
|
|
162
|
+
return applied;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=admin-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-view.js","sourceRoot":"","sources":["../src/admin-view.ts"],"names":[],"mappings":"AAmBA;+DAC+D;AAC/D,MAAM,CAAC,MAAM,iBAAiB,GAAmB;IAC/C,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,YAAY,EAAE,wCAAwC;IACtD,eAAe,EAAE,yCAAyC;IAC1D,OAAO,EAAE,SAAS;CACnB,CAAC;AAiCF,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,SAAS,cAAc,CAAC,KAAyB;IAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,WAAW,CAAC;IAC9E,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,OAAqB,EAAE,IAAe;IACpD,MAAM,GAAG,GAAa;QACpB,SAAS,EAAE,OAAO,CAAC,EAAE;QACrB,YAAY,EAAE,OAAO,CAAC,KAAK;QAC3B,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;QACrC,OAAO,EAAE,MAAM;KAChB,CAAC;IACF,IAAI,IAAI,CAAC,WAAW,KAAK,SAAS;QAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;IAEvE,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC;YACvB,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBACpC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC;gBACpB,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC;YACtB,CAAC;YACD,MAAM;QACR,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC;YACvB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;YACtB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1F,GAAG,CAAC,QAAQ,GAAG,OAAO,CAAC;YACvB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC;YACvD,IAAI,KAAK;gBAAE,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;YACvC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC;YAC9C,MAAM;QACR,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,GAAG,CAAC,OAAO,GAAG,QAAQ,CAAC;YACvB,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC;YACnB,MAAM;QACR,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,oEAAoE;YACpE,sEAAsE;YACtE,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC;gBACrB,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;YACxB,CAAC;YACD,MAAM;QACR,CAAC;QACD;YACE,MAAM;IACV,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IAClD,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI;QAAE,GAAG,CAAC,eAAe,GAAG,IAAI,CAAC;IAC9D,OAAO,GAAG,CAAC;AACb,CAAC;AAED;4EAC4E;AAC5E,MAAM,UAAU,cAAc,CAAC,KAAoC;IACjE,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IACxD,MAAM,IAAI,GAAe,EAAE,CAAC;IAC5B,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAA+C,CAAC;IACvE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,SAAS;QACxD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAyC,CAAC;QAChE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ;gBAAE,SAAS;YACnD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,OAAO,CAAC,KAAoC;IAC1D,OAAO,KAAK,EAAE,EAAE,IAAI,iBAAiB,CAAC;AACxC,CAAC;AAED;iFACiF;AACjF,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,EAAkB;IAClE,OAAO,KAAK,KAAK,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7D,CAAC;AAaD,yDAAyD;AACzD,MAAM,UAAU,UAAU,CACxB,MAAyB,EACzB,OAAqB,EACrB,EAAkB;IAElB,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC;IACxF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,MAAM,GAAqC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACnF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC9D,OAAO;YACL,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,YAAY,EAAE,EAAE,CAAC,OAAO;YACxB,WAAW,EAAE,EAAE,CAAC,MAAM;YACtB,MAAM;SACP,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAoB;QAC/B,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,MAAM,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO;QAC1E,OAAO,EAAE,IAAI;KACd,CAAC;IACF,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IACjE,OAAO,OAAO,CAAC;AACjB,CAAC;AAYD,MAAM,UAAU,mBAAmB;IACjC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,aAAa,CAAC,MAAoB,EAAE,KAAmB;IACrE,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACtD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACjE,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IACzF,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IAChF,MAAM,OAAO,GAAiB,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IAC5E,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAClD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|