nixamp 0.7.25 → 0.7.26
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/dist/admin.d.ts +10 -0
- package/dist/admin.js +23 -4
- package/dist/daemon.d.ts +7 -0
- package/dist/daemon.js +14 -1
- package/dist/server.js +4 -0
- package/package.json +1 -1
- package/src/admin.ts +34 -4
- package/src/daemon.ts +22 -1
- package/src/server.ts +4 -0
- package/web/dist/sw.js +1 -1
package/dist/admin.d.ts
CHANGED
|
@@ -39,6 +39,14 @@ export interface AdminOptions {
|
|
|
39
39
|
label: string;
|
|
40
40
|
url: string;
|
|
41
41
|
}[];
|
|
42
|
+
/**
|
|
43
|
+
* The key that only watches, when this server has one.
|
|
44
|
+
*
|
|
45
|
+
* The links built from it are the ones to hand other people. Absent when
|
|
46
|
+
* pointed at a server by hand, since a listening key is not something you
|
|
47
|
+
* can work out from a control one.
|
|
48
|
+
*/
|
|
49
|
+
listenKey?: string | null;
|
|
42
50
|
/** What it is serving, so the admin view says so without being asked. */
|
|
43
51
|
source: string;
|
|
44
52
|
}
|
|
@@ -76,6 +84,8 @@ export interface View {
|
|
|
76
84
|
url: string;
|
|
77
85
|
}[];
|
|
78
86
|
key: string | null;
|
|
87
|
+
/** The key that only watches, for the links you hand to other people. */
|
|
88
|
+
listenKey?: string | null;
|
|
79
89
|
source: string;
|
|
80
90
|
}
|
|
81
91
|
export declare function draw(ui: Container, theme: Theme, view: View): void;
|
package/dist/admin.js
CHANGED
|
@@ -39,6 +39,7 @@ export function resolveTarget(argv) {
|
|
|
39
39
|
return {
|
|
40
40
|
url: url_,
|
|
41
41
|
key: key ?? state.key,
|
|
42
|
+
...(state.listenKey ? { listenKey: state.listenKey } : {}),
|
|
42
43
|
// A state file written before 0.5.3 has no list; loopback stands in.
|
|
43
44
|
links: state.urls ?? [{ label: "here", url: daemonUrl(state) }],
|
|
44
45
|
source: state.source,
|
|
@@ -176,7 +177,7 @@ export async function admin(argv) {
|
|
|
176
177
|
app.on("exit", () => clearInterval(timer));
|
|
177
178
|
app.render(({ ui, theme }) => draw(ui, theme, {
|
|
178
179
|
url: target.url, report, snapshot, error, typing, restreaming, replacing,
|
|
179
|
-
links: target.links, key: target.key, source: target.source,
|
|
180
|
+
links: target.links, key: target.key, listenKey: target.listenKey, source: target.source,
|
|
180
181
|
}));
|
|
181
182
|
await app.start();
|
|
182
183
|
clearInterval(timer);
|
|
@@ -229,13 +230,31 @@ export function draw(ui, theme, view) {
|
|
|
229
230
|
// reach it. The key is on them: without it every address is a 401.
|
|
230
231
|
if (view.links.length > 0) {
|
|
231
232
|
const width = Math.max(...view.links.map((link) => link.label.length));
|
|
232
|
-
|
|
233
|
+
// Both kinds, labelled, because they are not interchangeable and the
|
|
234
|
+
// operator had only ever been shown the one that drives. Handing that to
|
|
235
|
+
// somebody who wanted to watch hands them the controls with it, and
|
|
236
|
+
// there was nothing else to hand them.
|
|
237
|
+
// Counted rather than guessed: a heading of its own, the links, the second
|
|
238
|
+
// heading and its links when there is a viewing key, the source, and the
|
|
239
|
+
// two borders. A panel one line short silently drops the last row.
|
|
240
|
+
const rows = 1 + view.links.length
|
|
241
|
+
+ (view.listenKey ? 1 + view.links.length : 0)
|
|
242
|
+
+ (view.source ? 1 : 0);
|
|
243
|
+
ui.panel({ title: "Your links, and the ones to share", size: rows + 2 }, (p) => {
|
|
244
|
+
p.label("Yours -- these administer this server:");
|
|
233
245
|
for (const link of view.links) {
|
|
234
|
-
|
|
235
|
-
p.text(`${link.label.padEnd(width)} ${full}`, {
|
|
246
|
+
p.text(`${link.label.padEnd(width)} ${shareLink(link.url, view.key)}`, {
|
|
236
247
|
fg: link.label === "on the internet" ? theme.accent : theme.foreground,
|
|
237
248
|
});
|
|
238
249
|
}
|
|
250
|
+
if (view.listenKey) {
|
|
251
|
+
p.label("To share -- these watch and listen, and change nothing:");
|
|
252
|
+
for (const link of view.links) {
|
|
253
|
+
p.text(`${link.label.padEnd(width)} ${shareLink(link.url, view.listenKey, false)}`, {
|
|
254
|
+
fg: link.label === "on the internet" ? theme.accent : theme.foreground,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
239
258
|
if (view.source)
|
|
240
259
|
p.label(view.source);
|
|
241
260
|
});
|
package/dist/daemon.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ export interface DaemonState {
|
|
|
4
4
|
port: number;
|
|
5
5
|
/** The share key, so `nixamp admin` can talk to it without being told. */
|
|
6
6
|
key: string | null;
|
|
7
|
+
/**
|
|
8
|
+
* The key that only views, for handing to somebody who should watch.
|
|
9
|
+
*
|
|
10
|
+
* Absent on a state file written by an older nixamp, and absent on a server
|
|
11
|
+
* running with no key at all.
|
|
12
|
+
*/
|
|
13
|
+
listenKey?: string | null;
|
|
7
14
|
source: string;
|
|
8
15
|
startedAt: number;
|
|
9
16
|
/** Where its output went, for when it died and you want to know why. */
|
package/dist/daemon.js
CHANGED
|
@@ -121,8 +121,11 @@ function spell(ms) {
|
|
|
121
121
|
* typed the command.
|
|
122
122
|
*/
|
|
123
123
|
export function daemonLines(state, uptimeMs) {
|
|
124
|
-
//
|
|
124
|
+
// Two links per address: the one that drives this server and the one that
|
|
125
|
+
// only watches it. Printing just the first left the operator with nothing to
|
|
126
|
+
// hand anybody -- and handing over the wrong one hands over the controls.
|
|
125
127
|
const link = (url) => shareLink(url, state.key ?? null);
|
|
128
|
+
const viewLink = (url) => shareLink(url, state.listenKey ?? null, false);
|
|
126
129
|
// A state file written by an older nixamp has no list, so host and port
|
|
127
130
|
// still stand in rather than printing nothing at all.
|
|
128
131
|
const addresses = state.urls ?? [{ label: "here", url: daemonUrl(state) }];
|
|
@@ -131,6 +134,15 @@ export function daemonLines(state, uptimeMs) {
|
|
|
131
134
|
for (const { label, url } of addresses)
|
|
132
135
|
lines.push(` ${label.padEnd(width)} ${link(url)}`);
|
|
133
136
|
lines.push(` ${"source".padEnd(width)} ${state.source}`);
|
|
137
|
+
// The viewing links, said separately and said as what they are. Somebody who
|
|
138
|
+
// should be able to watch your library should not be handed the link that
|
|
139
|
+
// re-streams it, and the operator had nothing else to give them.
|
|
140
|
+
if (state.listenKey) {
|
|
141
|
+
lines.push("", " To share -- these watch and listen, and change nothing:");
|
|
142
|
+
for (const { label, url } of addresses) {
|
|
143
|
+
lines.push(` ${label.padEnd(width)} ${viewLink(url)}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
134
146
|
if (uptimeMs !== undefined)
|
|
135
147
|
lines.push(` ${"up".padEnd(width)} ${spell(uptimeMs)}`);
|
|
136
148
|
if (state.guessedPublic) {
|
|
@@ -227,6 +239,7 @@ async function waitForAnnounce(log, timeoutMs) {
|
|
|
227
239
|
host: String(parsed["host"]),
|
|
228
240
|
port: Number(parsed["port"]),
|
|
229
241
|
key: parsed["key"] ?? null,
|
|
242
|
+
...(typeof parsed["listenKey"] === "string" ? { listenKey: parsed["listenKey"] } : {}),
|
|
230
243
|
source: String(parsed["source"]),
|
|
231
244
|
...(Array.isArray(urls) ? { urls: urls } : {}),
|
|
232
245
|
...(typeof parsed["firewall"] === "string" ? { firewall: parsed["firewall"] } : {}),
|
package/dist/server.js
CHANGED
|
@@ -2962,6 +2962,10 @@ export async function serve(argv, version = "0.1.0") {
|
|
|
2962
2962
|
host: options.host,
|
|
2963
2963
|
port,
|
|
2964
2964
|
key,
|
|
2965
|
+
// The other half of the pair. Without it `nixamp admin` can only draw
|
|
2966
|
+
// the links that administer, so the operator has nothing to hand
|
|
2967
|
+
// somebody who should be able to watch and not to drive.
|
|
2968
|
+
listenKey,
|
|
2965
2969
|
source: root,
|
|
2966
2970
|
urls: addresses,
|
|
2967
2971
|
firewall,
|
package/package.json
CHANGED
package/src/admin.ts
CHANGED
|
@@ -38,6 +38,14 @@ export interface AdminOptions {
|
|
|
38
38
|
* anybody. These are the ones worth reading off the screen.
|
|
39
39
|
*/
|
|
40
40
|
links: { label: string; url: string }[];
|
|
41
|
+
/**
|
|
42
|
+
* The key that only watches, when this server has one.
|
|
43
|
+
*
|
|
44
|
+
* The links built from it are the ones to hand other people. Absent when
|
|
45
|
+
* pointed at a server by hand, since a listening key is not something you
|
|
46
|
+
* can work out from a control one.
|
|
47
|
+
*/
|
|
48
|
+
listenKey?: string | null;
|
|
41
49
|
/** What it is serving, so the admin view says so without being asked. */
|
|
42
50
|
source: string;
|
|
43
51
|
}
|
|
@@ -76,6 +84,7 @@ export function resolveTarget(argv: string[]): AdminOptions {
|
|
|
76
84
|
return {
|
|
77
85
|
url: url_,
|
|
78
86
|
key: key ?? state.key,
|
|
87
|
+
...(state.listenKey ? { listenKey: state.listenKey } : {}),
|
|
79
88
|
// A state file written before 0.5.3 has no list; loopback stands in.
|
|
80
89
|
links: state.urls ?? [{ label: "here", url: daemonUrl(state) }],
|
|
81
90
|
source: state.source,
|
|
@@ -198,7 +207,7 @@ export async function admin(argv: string[]): Promise<void> {
|
|
|
198
207
|
app.on("exit", () => clearInterval(timer));
|
|
199
208
|
app.render(({ ui, theme }) => draw(ui, theme, {
|
|
200
209
|
url: target.url, report, snapshot, error, typing, restreaming, replacing,
|
|
201
|
-
links: target.links, key: target.key, source: target.source,
|
|
210
|
+
links: target.links, key: target.key, listenKey: target.listenKey, source: target.source,
|
|
202
211
|
}));
|
|
203
212
|
|
|
204
213
|
await app.start();
|
|
@@ -242,6 +251,8 @@ export interface View {
|
|
|
242
251
|
/** Labelled addresses, and the key that makes them work. */
|
|
243
252
|
links: { label: string; url: string }[];
|
|
244
253
|
key: string | null;
|
|
254
|
+
/** The key that only watches, for the links you hand to other people. */
|
|
255
|
+
listenKey?: string | null;
|
|
245
256
|
source: string;
|
|
246
257
|
}
|
|
247
258
|
|
|
@@ -276,13 +287,32 @@ export function draw(ui: Container, theme: Theme, view: View): void {
|
|
|
276
287
|
// reach it. The key is on them: without it every address is a 401.
|
|
277
288
|
if (view.links.length > 0) {
|
|
278
289
|
const width = Math.max(...view.links.map((link) => link.label.length));
|
|
279
|
-
|
|
290
|
+
// Both kinds, labelled, because they are not interchangeable and the
|
|
291
|
+
// operator had only ever been shown the one that drives. Handing that to
|
|
292
|
+
// somebody who wanted to watch hands them the controls with it, and
|
|
293
|
+
// there was nothing else to hand them.
|
|
294
|
+
// Counted rather than guessed: a heading of its own, the links, the second
|
|
295
|
+
// heading and its links when there is a viewing key, the source, and the
|
|
296
|
+
// two borders. A panel one line short silently drops the last row.
|
|
297
|
+
const rows =
|
|
298
|
+
1 + view.links.length
|
|
299
|
+
+ (view.listenKey ? 1 + view.links.length : 0)
|
|
300
|
+
+ (view.source ? 1 : 0);
|
|
301
|
+
ui.panel({ title: "Your links, and the ones to share", size: rows + 2 }, (p) => {
|
|
302
|
+
p.label("Yours -- these administer this server:");
|
|
280
303
|
for (const link of view.links) {
|
|
281
|
-
|
|
282
|
-
p.text(`${link.label.padEnd(width)} ${full}`, {
|
|
304
|
+
p.text(`${link.label.padEnd(width)} ${shareLink(link.url, view.key)}`, {
|
|
283
305
|
fg: link.label === "on the internet" ? theme.accent : theme.foreground,
|
|
284
306
|
});
|
|
285
307
|
}
|
|
308
|
+
if (view.listenKey) {
|
|
309
|
+
p.label("To share -- these watch and listen, and change nothing:");
|
|
310
|
+
for (const link of view.links) {
|
|
311
|
+
p.text(`${link.label.padEnd(width)} ${shareLink(link.url, view.listenKey, false)}`, {
|
|
312
|
+
fg: link.label === "on the internet" ? theme.accent : theme.foreground,
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
}
|
|
286
316
|
if (view.source) p.label(view.source);
|
|
287
317
|
});
|
|
288
318
|
}
|
package/src/daemon.ts
CHANGED
|
@@ -18,6 +18,13 @@ export interface DaemonState {
|
|
|
18
18
|
port: number;
|
|
19
19
|
/** The share key, so `nixamp admin` can talk to it without being told. */
|
|
20
20
|
key: string | null;
|
|
21
|
+
/**
|
|
22
|
+
* The key that only views, for handing to somebody who should watch.
|
|
23
|
+
*
|
|
24
|
+
* Absent on a state file written by an older nixamp, and absent on a server
|
|
25
|
+
* running with no key at all.
|
|
26
|
+
*/
|
|
27
|
+
listenKey?: string | null;
|
|
21
28
|
source: string;
|
|
22
29
|
startedAt: number;
|
|
23
30
|
/** Where its output went, for when it died and you want to know why. */
|
|
@@ -164,8 +171,11 @@ function spell(ms: number): string {
|
|
|
164
171
|
* typed the command.
|
|
165
172
|
*/
|
|
166
173
|
export function daemonLines(state: DaemonState, uptimeMs?: number): string[] {
|
|
167
|
-
//
|
|
174
|
+
// Two links per address: the one that drives this server and the one that
|
|
175
|
+
// only watches it. Printing just the first left the operator with nothing to
|
|
176
|
+
// hand anybody -- and handing over the wrong one hands over the controls.
|
|
168
177
|
const link = (url: string): string => shareLink(url, state.key ?? null);
|
|
178
|
+
const viewLink = (url: string): string => shareLink(url, state.listenKey ?? null, false);
|
|
169
179
|
// A state file written by an older nixamp has no list, so host and port
|
|
170
180
|
// still stand in rather than printing nothing at all.
|
|
171
181
|
const addresses = state.urls ?? [{ label: "here", url: daemonUrl(state) }];
|
|
@@ -174,6 +184,16 @@ export function daemonLines(state: DaemonState, uptimeMs?: number): string[] {
|
|
|
174
184
|
const lines = [`nixamp daemon running (pid ${state.pid})`];
|
|
175
185
|
for (const { label, url } of addresses) lines.push(` ${label.padEnd(width)} ${link(url)}`);
|
|
176
186
|
lines.push(` ${"source".padEnd(width)} ${state.source}`);
|
|
187
|
+
|
|
188
|
+
// The viewing links, said separately and said as what they are. Somebody who
|
|
189
|
+
// should be able to watch your library should not be handed the link that
|
|
190
|
+
// re-streams it, and the operator had nothing else to give them.
|
|
191
|
+
if (state.listenKey) {
|
|
192
|
+
lines.push("", " To share -- these watch and listen, and change nothing:");
|
|
193
|
+
for (const { label, url } of addresses) {
|
|
194
|
+
lines.push(` ${label.padEnd(width)} ${viewLink(url)}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
177
197
|
if (uptimeMs !== undefined) lines.push(` ${"up".padEnd(width)} ${spell(uptimeMs)}`);
|
|
178
198
|
|
|
179
199
|
if (state.guessedPublic) {
|
|
@@ -300,6 +320,7 @@ async function waitForAnnounce(
|
|
|
300
320
|
host: String(parsed["host"]),
|
|
301
321
|
port: Number(parsed["port"]),
|
|
302
322
|
key: (parsed["key"] as string | null) ?? null,
|
|
323
|
+
...(typeof parsed["listenKey"] === "string" ? { listenKey: parsed["listenKey"] } : {}),
|
|
303
324
|
source: String(parsed["source"]),
|
|
304
325
|
...(Array.isArray(urls) ? { urls: urls as { label: string; url: string }[] } : {}),
|
|
305
326
|
...(typeof parsed["firewall"] === "string" ? { firewall: parsed["firewall"] } : {}),
|
package/src/server.ts
CHANGED
|
@@ -3447,6 +3447,10 @@ export async function serve(argv: string[], version = "0.1.0"): Promise<void> {
|
|
|
3447
3447
|
host: options.host,
|
|
3448
3448
|
port,
|
|
3449
3449
|
key,
|
|
3450
|
+
// The other half of the pair. Without it `nixamp admin` can only draw
|
|
3451
|
+
// the links that administer, so the operator has nothing to hand
|
|
3452
|
+
// somebody who should be able to watch and not to drive.
|
|
3453
|
+
listenKey,
|
|
3450
3454
|
source: root,
|
|
3451
3455
|
urls: addresses,
|
|
3452
3456
|
firewall,
|
package/web/dist/sw.js
CHANGED