@fedify/cli 2.1.0 → 2.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/dist/nodeinfo.js CHANGED
@@ -1,13 +1,11 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  import { configContext } from "./config.js";
5
3
  import { userAgentOption } from "./options.js";
6
4
  import { colors, formatObject } from "./utils.js";
7
- import os from "node:os";
8
- import process from "node:process";
9
5
  import { argument, command, constant, flag, group, merge, message, object, string, text } from "@optique/core";
10
6
  import { print, printError } from "@optique/run";
7
+ import os from "node:os";
8
+ import process from "node:process";
11
9
  import { bindConfig } from "@optique/config";
12
10
  import { getNodeInfo } from "@fedify/fedify";
13
11
  import { getLogger } from "@logtape/logtape";
@@ -17,7 +15,6 @@ import { createJimp } from "@jimp/core";
17
15
  import webp from "@jimp/wasm-webp";
18
16
  import { isICO, parseICO } from "icojs";
19
17
  import { defaultFormats, defaultPlugins, intToRGBA } from "jimp";
20
-
21
18
  //#region src/nodeinfo.ts
22
19
  const logger = getLogger([
23
20
  "fedify",
@@ -58,44 +55,44 @@ const nodeInfoCommand = command("nodeinfo", merge(object("Arguments", {
58
55
 
59
56
  The argument is the hostname of the remote node, or the URL of the remote node.`
60
57
  });
61
- async function runNodeInfo(command$1) {
58
+ async function runNodeInfo(command) {
62
59
  const spinner = ora({
63
60
  text: "Fetching a NodeInfo document...",
64
61
  discardStdin: false
65
62
  }).start();
66
- const url = new URL(URL.canParse(command$1.host) ? command$1.host : `https://${command$1.host}`);
67
- if (command$1.raw) {
68
- const nodeInfo$1 = await getNodeInfo(url, {
63
+ const url = new URL(URL.canParse(command.host) ? command.host : `https://${command.host}`);
64
+ if (command.raw) {
65
+ const nodeInfo = await getNodeInfo(url, {
69
66
  parse: "none",
70
- userAgent: command$1.userAgent
67
+ userAgent: command.userAgent
71
68
  });
72
- if (nodeInfo$1 === void 0) {
69
+ if (nodeInfo === void 0) {
73
70
  spinner.fail("No NodeInfo document found.");
74
71
  printError(message`No NodeInfo document found.`);
75
72
  process.exit(1);
76
73
  }
77
74
  spinner.succeed("NodeInfo document fetched.");
78
- print(message`${text(formatObject(nodeInfo$1, void 0, true))}`);
75
+ print(message`${text(formatObject(nodeInfo, void 0, true))}`);
79
76
  return;
80
77
  }
81
78
  const nodeInfo = await getNodeInfo(url, {
82
- parse: command$1.bestEffort ? "best-effort" : "strict",
83
- userAgent: command$1.userAgent
79
+ parse: command.bestEffort ? "best-effort" : "strict",
80
+ userAgent: command.userAgent
84
81
  });
85
82
  logger.debug("NodeInfo document: {nodeInfo}", { nodeInfo });
86
83
  if (nodeInfo == void 0) {
87
84
  spinner.fail("No NodeInfo document found or it is invalid.");
88
85
  printError(message`No NodeInfo document found or it is invalid.`);
89
- if (!command$1.bestEffort) printError(message`Use the -b/--best-effort option to try to parse the document anyway.`);
86
+ if (!command.bestEffort) printError(message`Use the -b/--best-effort option to try to parse the document anyway.`);
90
87
  process.exit(1);
91
88
  }
92
89
  let layout;
93
90
  let defaultWidth = 0;
94
- if (!command$1.noFavicon) {
91
+ if (!command.noFavicon) {
95
92
  spinner.text = "Fetching the favicon...";
96
93
  try {
97
- const faviconUrl = await getFaviconUrl(url, command$1.userAgent);
98
- const response = await fetch(faviconUrl, { headers: { "User-Agent": command$1.userAgent == null ? getUserAgent() : command$1.userAgent } });
94
+ const faviconUrl = await getFaviconUrl(url, command.userAgent);
95
+ const response = await fetch(faviconUrl, { headers: { "User-Agent": command.userAgent == null ? getUserAgent() : command.userAgent } });
99
96
  if (response.ok) {
100
97
  const contentType = response.headers.get("Content-Type");
101
98
  let buffer = await response.arrayBuffer();
@@ -104,9 +101,7 @@ async function runNodeInfo(command$1) {
104
101
  if (images.length < 1) throw new Error("No images found in the ICO file.");
105
102
  buffer = images[0].buffer;
106
103
  }
107
- const image = await Jimp.read(buffer);
108
- const colorSupport = checkTerminalColorSupport();
109
- layout = getAsciiArt(image, DEFAULT_IMAGE_WIDTH, colorSupport, colors).split("\n").map((line) => ` ${line} `);
104
+ layout = getAsciiArt(await Jimp.read(buffer), DEFAULT_IMAGE_WIDTH, checkTerminalColorSupport(), colors).split("\n").map((line) => ` ${line} `);
110
105
  defaultWidth = 41;
111
106
  } else {
112
107
  logger.error("Failed to fetch the favicon: {status} {statusText}", {
@@ -164,25 +159,25 @@ async function runNodeInfo(command$1) {
164
159
  layout[next()] += colors.bold(colors.dim("Open registrations:"));
165
160
  layout[next()] += " " + (nodeInfo.openRegistrations ? "Yes" : "No");
166
161
  }
167
- if (command$1.metadata && nodeInfo.metadata != null && Object.keys(nodeInfo.metadata).length > 0) {
162
+ if (command.metadata && nodeInfo.metadata != null && Object.keys(nodeInfo.metadata).length > 0) {
168
163
  layout[next()] += colors.bold(colors.dim("Metadata:"));
169
- for (const [key, value$1] of Object.entries(nodeInfo.metadata)) layout[next()] += ` ${colors.dim(key + ":")} ${indent(typeof value$1 === "string" ? value$1 : formatObject(value$1), defaultWidth + 4 + key.length)}`;
164
+ for (const [key, value] of Object.entries(nodeInfo.metadata)) layout[next()] += ` ${colors.dim(key + ":")} ${indent(typeof value === "string" ? value : formatObject(value), defaultWidth + 4 + key.length)}`;
170
165
  }
171
166
  console.log(layout.join("\n"));
172
167
  }
173
- function indent(text$1, depth) {
174
- return text$1.replace(/\n/g, "\n" + " ".repeat(depth));
168
+ function indent(text, depth) {
169
+ return text.replace(/\n/g, "\n" + " ".repeat(depth));
175
170
  }
176
171
  const LINK_REGEXP = /<link((?:\s+(?:[-a-z]+)=(?:"[^"]*"|'[^']*'|[^\s]+))*)\s*\/?>/gi;
177
172
  const LINK_ATTRS_REGEXP = /(?:\s+([-a-z]+)=("[^"]*"|'[^']*'|[^\s]+))/gi;
178
173
  async function getFaviconUrl(url, userAgent) {
179
174
  const response = await fetch(url, { headers: { "User-Agent": userAgent == null ? getUserAgent() : userAgent } });
180
- const text$1 = await response.text();
181
- for (const match of text$1.matchAll(LINK_REGEXP)) {
175
+ const text = await response.text();
176
+ for (const match of text.matchAll(LINK_REGEXP)) {
182
177
  const attrs = {};
183
178
  for (const attrMatch of match[1].matchAll(LINK_ATTRS_REGEXP)) {
184
- const [, key, value$1] = attrMatch;
185
- attrs[key] = value$1.startsWith("\"") || value$1.startsWith("'") ? value$1.slice(1, -1) : value$1;
179
+ const [, key, value] = attrMatch;
180
+ attrs[key] = value.startsWith("\"") || value.startsWith("'") ? value.slice(1, -1) : value;
186
181
  }
187
182
  const rel = attrs.rel?.toLowerCase()?.trim()?.split(/\s+/) ?? [];
188
183
  if (!rel.includes("icon") && !rel.includes("apple-touch-icon")) continue;
@@ -220,11 +215,11 @@ const CUBE_VALUES = [
220
215
  215,
221
216
  255
222
217
  ];
223
- const findClosestIndex = (value$1) => {
218
+ const findClosestIndex = (value) => {
224
219
  let minDiff = Infinity;
225
220
  let closestIndex = 0;
226
221
  for (let idx = 0; idx < CUBE_VALUES.length; idx++) {
227
- const diff = Math.abs(value$1 - CUBE_VALUES[idx]);
222
+ const diff = Math.abs(value - CUBE_VALUES[idx]);
228
223
  if (diff < minDiff) {
229
224
  minDiff = diff;
230
225
  closestIndex = idx;
@@ -234,10 +229,8 @@ const findClosestIndex = (value$1) => {
234
229
  };
235
230
  function rgbTo256Color(r, g, b) {
236
231
  const gray = Math.round((r + g + b) / 3);
237
- const isGrayscale = Math.abs(r - gray) <= 5 && Math.abs(g - gray) <= 5 && Math.abs(b - gray) <= 5;
238
- if (isGrayscale) {
239
- const isExactCubeValue = CUBE_VALUES.includes(r) && r === g && g === b;
240
- if (!isExactCubeValue) {
232
+ if (Math.abs(r - gray) <= 5 && Math.abs(g - gray) <= 5 && Math.abs(b - gray) <= 5) {
233
+ if (!(CUBE_VALUES.includes(r) && r === g && g === b)) {
241
234
  if (gray < 8) return 232;
242
235
  if (gray > 238) return 255;
243
236
  const grayIndex = Math.round((gray - 8) / 10);
@@ -249,7 +242,7 @@ function rgbTo256Color(r, g, b) {
249
242
  const b6 = findClosestIndex(b);
250
243
  return 16 + 36 * r6 + 6 * g6 + b6;
251
244
  }
252
- function getAsciiArt(image, width = DEFAULT_IMAGE_WIDTH, colorSupport, colors$1) {
245
+ function getAsciiArt(image, width = DEFAULT_IMAGE_WIDTH, colorSupport, colors) {
253
246
  const ratio = image.width / image.height;
254
247
  const height = Math.round(width / ratio * .5);
255
248
  image.resize({
@@ -259,25 +252,22 @@ function getAsciiArt(image, width = DEFAULT_IMAGE_WIDTH, colorSupport, colors$1)
259
252
  let art = "";
260
253
  for (let y = 0; y < height; y++) {
261
254
  for (let x = 0; x < width; x++) {
262
- const pixel = image.getPixelColor(x, y);
263
- const color = intToRGBA(pixel);
255
+ const color = intToRGBA(image.getPixelColor(x, y));
264
256
  if (color.a < 1) {
265
257
  art += " ";
266
258
  continue;
267
259
  }
268
260
  const brightness = (color.r + color.g + color.b) / 3;
269
- const charIndex = Math.round(brightness / 255 * 72);
270
- const char = ASCII_CHARS[charIndex];
271
- if (colorSupport === "truecolor") art += colors$1.rgb(color.r, color.g, color.b)(char);
261
+ const char = ASCII_CHARS[Math.round(brightness / 255 * 72)];
262
+ if (colorSupport === "truecolor") art += colors.rgb(color.r, color.g, color.b)(char);
272
263
  else if (colorSupport === "256color") {
273
264
  const colorIndex = rgbTo256Color(color.r, color.g, color.b);
274
- art += colors$1.ansi256(colorIndex)(char);
265
+ art += colors.ansi256(colorIndex)(char);
275
266
  } else art += char;
276
267
  }
277
268
  if (y < height - 1) art += "\n";
278
269
  }
279
270
  return art;
280
271
  }
281
-
282
272
  //#endregion
283
- export { Jimp, nodeInfoCommand, runNodeInfo };
273
+ export { Jimp, nodeInfoCommand, runNodeInfo };
package/dist/options.js CHANGED
@@ -1,11 +1,8 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  import { configContext } from "./config.js";
5
3
  import { choice, constant, flag, map, merge, message, object, option, or, string, withDefault } from "@optique/core";
6
4
  import { bindConfig } from "@optique/config";
7
5
  import { getUserAgent } from "@fedify/vocab-runtime";
8
-
9
6
  //#region src/options.ts
10
7
  /**
11
8
  * Available tunneling services for exposing local servers to the public internet.
@@ -18,8 +15,8 @@ const TUNNEL_SERVICES = [
18
15
  /**
19
16
  * Creates a tunnel service option with customizable option names.
20
17
  */
21
- function createTunnelServiceOption(optionNames$1 = ["--tunnel-service"]) {
22
- return withDefault(bindConfig(option(...optionNames$1, choice(TUNNEL_SERVICES, { metavar: "SERVICE" }), { description: message`The tunneling service to use.
18
+ function createTunnelServiceOption(optionNames = ["--tunnel-service"]) {
19
+ return withDefault(bindConfig(option(...optionNames, choice(TUNNEL_SERVICES, { metavar: "SERVICE" }), { description: message`The tunneling service to use.
23
20
  By default, any of the supported tunneling services will be used
24
21
  (randomly selected for each tunnel).` }), {
25
22
  context: configContext,
@@ -54,31 +51,17 @@ const userAgentOption = object({ userAgent: bindConfig(option("-u", "--user-agen
54
51
  default: getUserAgent()
55
52
  }) });
56
53
  /**
57
- * Configuration file options.
58
- *
59
- * These options are mutually exclusive:
60
- * - `--config PATH` loads an additional config file on top of standard hierarchy
61
- * - `--ignore-config` skips all config files (useful for CI reproducibility)
54
+ * Global options that apply to all commands.
62
55
  *
63
- * Returns either:
64
- * - `{ ignoreConfig: true }` when `--ignore-config` is specified
65
- * - `{ ignoreConfig: false, configPath: string }` when `--config` is specified
66
- * - `{ ignoreConfig: false }` when neither is specified (default)
56
+ * Combines debug mode and configuration file options into a single
57
+ * "Global options" group.
67
58
  */
68
- const configOption = withDefault(or(object({ ignoreConfig: map(flag("--ignore-config", { description: message`Ignore all configuration files.` }), () => true) }), object({
59
+ const globalOptions = merge("Global options", debugOption, withDefault(or(object({ ignoreConfig: map(flag("--ignore-config", { description: message`Ignore all configuration files.` }), () => true) }), object({
69
60
  ignoreConfig: constant(false),
70
61
  configPath: option("--config", string({ metavar: "PATH" }), { description: message`Load an additional configuration file.` })
71
62
  })), {
72
63
  ignoreConfig: false,
73
64
  configPath: void 0
74
- });
75
- /**
76
- * Global options that apply to all commands.
77
- *
78
- * Combines debug mode and configuration file options into a single
79
- * "Global options" group.
80
- */
81
- const globalOptions = merge("Global options", debugOption, configOption);
82
-
65
+ }));
83
66
  //#endregion
84
- export { createTunnelOption, createTunnelServiceOption, globalOptions, userAgentOption };
67
+ export { createTunnelOption, createTunnelServiceOption, globalOptions, userAgentOption };
package/dist/relay.js CHANGED
@@ -1,24 +1,21 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  import { configContext } from "./config.js";
5
3
  import { configureLogging } from "./log.js";
6
4
  import { createTunnelOption } from "./options.js";
7
5
  import { tableStyle } from "./table.js";
8
6
  import { spawnTemporaryServer } from "./tempserver.js";
9
7
  import { colors, matchesActor } from "./utils.js";
10
- import { SqliteKvStore } from "@fedify/sqlite";
11
- import process from "node:process";
12
- import { DatabaseSync } from "node:sqlite";
13
8
  import { command, constant, group, integer, merge, message, multiple, object, option, optionName, optional, string, value } from "@optique/core";
9
+ import process from "node:process";
14
10
  import { bindConfig } from "@optique/config";
15
11
  import { MemoryKvStore } from "@fedify/fedify";
16
12
  import { getLogger } from "@logtape/logtape";
17
13
  import Table from "cli-table3";
18
14
  import ora from "ora";
19
15
  import { createRelay } from "@fedify/relay";
16
+ import { SqliteKvStore } from "@fedify/sqlite";
20
17
  import { choice as choice$1 } from "@optique/core/valueparser";
21
-
18
+ import { DatabaseSync } from "node:sqlite";
22
19
  //#region src/relay.ts
23
20
  const logger = getLogger([
24
21
  "fedify",
@@ -66,17 +63,16 @@ const relayCommand = command("relay", merge(object("Relay options", {
66
63
 
67
64
  By default, the server is tunneled to the public internet for external access. Use ${optionName("--no-tunnel")} to run locally only.`
68
65
  });
69
- async function runRelay(command$1) {
70
- if (command$1.debug) await configureLogging();
66
+ async function runRelay(command) {
67
+ if (command.debug) await configureLogging();
71
68
  const spinner = ora({
72
69
  text: "Starting relay server...",
73
70
  discardStdin: false
74
71
  }).start();
75
72
  let kv;
76
- if (command$1.persistent) {
77
- logger.debug("Using SQLite storage at {path}.", { path: command$1.persistent });
78
- const db = new DatabaseSync(command$1.persistent);
79
- kv = new SqliteKvStore(db);
73
+ if (command.persistent) {
74
+ logger.debug("Using SQLite storage at {path}.", { path: command.persistent });
75
+ kv = new SqliteKvStore(new DatabaseSync(command.persistent));
80
76
  } else {
81
77
  logger.debug("Using in-memory storage.");
82
78
  kv = new MemoryKvStore();
@@ -85,18 +81,18 @@ async function runRelay(command$1) {
85
81
  let server = null;
86
82
  const acceptFollows = [];
87
83
  const rejectFollows = [];
88
- if (command$1.acceptFollow != null && command$1.acceptFollow.length > 0) acceptFollows.push(...command$1.acceptFollow ?? []);
89
- if (command$1.rejectFollow != null && command$1.rejectFollow.length > 0) rejectFollows.push(...command$1.rejectFollow ?? []);
84
+ if (command.acceptFollow != null && command.acceptFollow.length > 0) acceptFollows.push(...command.acceptFollow ?? []);
85
+ if (command.rejectFollow != null && command.rejectFollow.length > 0) rejectFollows.push(...command.rejectFollow ?? []);
90
86
  server = await spawnTemporaryServer(async (request) => {
91
87
  return await relay.fetch(request);
92
88
  }, {
93
- noTunnel: !command$1.tunnel,
94
- port: command$1.port,
95
- ...command$1.tunnel && { service: command$1.tunnelService }
89
+ noTunnel: !command.tunnel,
90
+ port: command.port,
91
+ ...command.tunnel && { service: command.tunnelService }
96
92
  });
97
- relay = createRelay(command$1.protocol, {
93
+ relay = createRelay(command.protocol, {
98
94
  origin: server?.url.origin,
99
- name: command$1.name,
95
+ name: command.name,
100
96
  kv,
101
97
  subscriptionHandler: async (_ctx, actor) => {
102
98
  const isInAcceptList = await matchesActor(actor, acceptFollows);
@@ -106,9 +102,9 @@ async function runRelay(command$1) {
106
102
  });
107
103
  spinner.succeed(`Relay server is running: ${colors.green(server.url.href)}`);
108
104
  await printRelayInfo(relay, {
109
- protocol: command$1.protocol,
110
- name: command$1.name,
111
- persistent: command$1.persistent
105
+ protocol: command.protocol,
106
+ name: command.name,
107
+ persistent: command.persistent
112
108
  });
113
109
  process.on("SIGINT", async () => {
114
110
  spinner.start("Shutting down relay server...");
@@ -131,6 +127,5 @@ async function printRelayInfo(relay, options) {
131
127
  console.log(table.toString());
132
128
  console.log("\nPress ^C to stop the relay server.");
133
129
  }
134
-
135
130
  //#endregion
136
- export { relayCommand, runRelay };
131
+ export { relayCommand, runRelay };
package/dist/table.js CHANGED
@@ -1,6 +1,4 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  //#region src/table.ts
5
3
  const tableStyle = {
6
4
  top: "─",
@@ -19,6 +17,5 @@ const tableStyle = {
19
17
  rightMid: "┤",
20
18
  middle: "│"
21
19
  };
22
-
23
20
  //#endregion
24
- export { tableStyle };
21
+ export { tableStyle };
@@ -1,10 +1,7 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  import { getLogger } from "@logtape/logtape";
5
3
  import { openTunnel } from "@hongminhee/localtunnel";
6
4
  import { serve } from "srvx";
7
-
8
5
  //#region src/tempserver.ts
9
6
  const logger = getLogger([
10
7
  "fedify",
@@ -14,28 +11,27 @@ const logger = getLogger([
14
11
  async function spawnTemporaryServer(fetch, options = {}) {
15
12
  const serverPort = options.port ?? 0;
16
13
  if (options.noTunnel) {
17
- const server$1 = serve({
14
+ const server = serve({
18
15
  port: serverPort,
19
16
  hostname: "::",
20
17
  silent: true,
21
18
  fetch
22
19
  });
23
- await server$1.ready();
24
- const url$1 = new URL(server$1.url);
25
- const port$1 = url$1.port;
26
- logger.debug("Temporary server is listening on port {port}.", { port: port$1 });
20
+ await server.ready();
21
+ const port = new URL(server.url).port;
22
+ logger.debug("Temporary server is listening on port {port}.", { port });
27
23
  return {
28
- url: new URL(`http://localhost:${port$1}`),
24
+ url: new URL(`http://localhost:${port}`),
29
25
  async close() {
30
- await server$1.close();
26
+ await server.close();
31
27
  }
32
28
  };
33
29
  }
34
30
  const server = serve({
35
31
  fetch: "Deno" in globalThis ? (request) => {
36
- const url$1 = new URL(request.url);
37
- url$1.protocol = "https:";
38
- const newRequest = new Request(url$1, {
32
+ const url = new URL(request.url);
33
+ url.protocol = "https:";
34
+ return fetch(new Request(url, {
39
35
  method: request.method,
40
36
  headers: request.headers,
41
37
  body: request.method === "GET" || request.method === "HEAD" ? null : request.body,
@@ -48,8 +44,7 @@ async function spawnTemporaryServer(fetch, options = {}) {
48
44
  integrity: request.integrity,
49
45
  keepalive: request.keepalive,
50
46
  signal: request.signal
51
- });
52
- return fetch(newRequest);
47
+ }));
53
48
  } : fetch,
54
49
  port: serverPort,
55
50
  hostname: "::",
@@ -57,8 +52,7 @@ async function spawnTemporaryServer(fetch, options = {}) {
57
52
  protocol: "https"
58
53
  });
59
54
  await server.ready();
60
- const url = new URL(server.url);
61
- const port = url.port;
55
+ const port = new URL(server.url).port;
62
56
  logger.debug("Temporary server is listening on port {port}.", { port });
63
57
  const tun = await openTunnel({
64
58
  port: parseInt(port),
@@ -73,6 +67,5 @@ async function spawnTemporaryServer(fetch, options = {}) {
73
67
  }
74
68
  };
75
69
  }
76
-
77
70
  //#endregion
78
- export { spawnTemporaryServer };
71
+ export { spawnTemporaryServer };
package/dist/tunnel.js CHANGED
@@ -1,14 +1,11 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  import { configureLogging } from "./log.js";
5
3
  import { createTunnelServiceOption } from "./options.js";
6
- import process from "node:process";
7
4
  import { argument, command, constant, integer, merge, message, object } from "@optique/core";
8
5
  import { print, printError } from "@optique/run";
6
+ import process from "node:process";
9
7
  import ora from "ora";
10
8
  import { openTunnel } from "@hongminhee/localtunnel";
11
-
12
9
  //#region src/tunnel.ts
13
10
  const tunnelCommand = command("tunnel", merge("Tunnel options", object({ command: constant("tunnel") }), object({
14
11
  port: argument(integer({
@@ -23,12 +20,12 @@ const tunnelCommand = command("tunnel", merge("Tunnel options", object({ command
23
20
 
24
21
  Note that the HTTP requests through the tunnel have X-Forwarded-* headers.`
25
22
  });
26
- async function runTunnel(command$1, deps = {
23
+ async function runTunnel(command, deps = {
27
24
  openTunnel,
28
25
  ora,
29
26
  exit: process.exit
30
27
  }) {
31
- if (command$1.debug) await configureLogging();
28
+ if (command.debug) await configureLogging();
32
29
  const spinner = deps.ora({
33
30
  text: "Creating a secure tunnel...",
34
31
  discardStdin: false
@@ -36,21 +33,20 @@ async function runTunnel(command$1, deps = {
36
33
  let tunnel;
37
34
  try {
38
35
  tunnel = await deps.openTunnel({
39
- port: command$1.port,
40
- service: command$1.service
36
+ port: command.port,
37
+ service: command.service
41
38
  });
42
39
  } catch (error) {
43
- if (command$1.debug) printError(message`${String(error)}`);
40
+ if (command.debug) printError(message`${String(error)}`);
44
41
  spinner.fail("Failed to create a secure tunnel.");
45
42
  deps.exit(1);
46
43
  }
47
- spinner.succeed(`Your local server at ${command$1.port} is now publicly accessible:\n`);
44
+ spinner.succeed(`Your local server at ${command.port} is now publicly accessible:\n`);
48
45
  print(message`${tunnel.url.href}`);
49
46
  print(message`\nPress ^C to close the tunnel.`);
50
47
  process.on("SIGINT", async () => {
51
48
  await tunnel.close();
52
49
  });
53
50
  }
54
-
55
51
  //#endregion
56
- export { runTunnel, tunnelCommand };
52
+ export { runTunnel, tunnelCommand };
package/dist/utils.js CHANGED
@@ -1,23 +1,18 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
4
- import "node:fs/promises";
5
- import process from "node:process";
1
+ import "@js-temporal/polyfill";
6
2
  import { message } from "@optique/core";
7
3
  import { print, printError } from "@optique/run";
8
4
  import { flow } from "es-toolkit";
5
+ import process from "node:process";
9
6
  import { getActorHandle } from "@fedify/vocab";
10
7
  import util from "node:util";
11
8
  import "@fxts/core";
12
9
  import { Chalk } from "chalk";
13
10
  import { highlight } from "cli-highlight";
14
- import "node:child_process";
15
-
16
11
  //#region src/utils.ts
17
12
  const colorEnabled = process.stdout.isTTY && !("NO_COLOR" in process.env && process.env.NO_COLOR !== "");
18
13
  const colors = new Chalk(colorEnabled ? {} : { level: 0 });
19
- function formatObject(obj, colors$1, json) {
20
- const enableColors = colors$1 ?? colorEnabled;
14
+ function formatObject(obj, colors, json) {
15
+ const enableColors = colors ?? colorEnabled;
21
16
  if (!json) return util.inspect(obj, { colors: enableColors });
22
17
  const formatted = JSON.stringify(obj, null, 2);
23
18
  if (enableColors) return highlight(formatted, { language: "json" });
@@ -38,8 +33,7 @@ async function matchesActor(actor, actorList) {
38
33
  }
39
34
  return false;
40
35
  }
41
- const printMessage = flow(message, print);
42
- const printErrorMessage = flow(message, printError);
43
-
36
+ flow(message, print);
37
+ flow(message, printError);
44
38
  //#endregion
45
- export { colorEnabled, colors, formatObject, matchesActor };
39
+ export { colorEnabled, colors, formatObject, matchesActor };
@@ -1,6 +1,4 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  import { formatObject } from "../utils.js";
5
3
  import { NotFoundError, getErrorMessage } from "./error.js";
6
4
  import { convertUrlIfHandle } from "./lib.js";
@@ -8,18 +6,15 @@ import { print } from "@optique/run";
8
6
  import { formatMessage, message } from "@optique/core/message";
9
7
  import ora from "ora";
10
8
  import { lookupWebFinger } from "@fedify/webfinger";
11
-
12
9
  //#region src/webfinger/action.ts
13
- async function runWebFinger({ command: _, resources,...options }) {
10
+ async function runWebFinger({ command: _, resources, ...options }) {
14
11
  await Array.fromAsync(resources.map((resource) => ({
15
12
  resource,
16
13
  ...options
17
14
  })), spinnerWrapper(lookupSingleWebFinger));
18
15
  }
19
- async function lookupSingleWebFinger({ resource,...options }) {
20
- const url = convertUrlIfHandle(resource);
21
- const webFinger = await lookupWebFinger(url, options) ?? new NotFoundError(resource).throw();
22
- return webFinger;
16
+ async function lookupSingleWebFinger({ resource, ...options }) {
17
+ return await lookupWebFinger(convertUrlIfHandle(resource), options) ?? new NotFoundError(resource).throw();
23
18
  }
24
19
  function spinnerWrapper(func) {
25
20
  return async (...args) => {
@@ -39,6 +34,5 @@ function spinnerWrapper(func) {
39
34
  }
40
35
  };
41
36
  }
42
-
43
37
  //#endregion
44
- export { runWebFinger };
38
+ export { runWebFinger as default };
@@ -1,11 +1,8 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  import { configContext } from "../config.js";
5
3
  import { userAgentOption } from "../options.js";
6
4
  import { argument, command, constant, flag, group, integer, merge, message, multiple, object, option, string } from "@optique/core";
7
5
  import { bindConfig } from "@optique/config";
8
-
9
6
  //#region src/webfinger/command.ts
10
7
  const allowPrivateAddresses = bindConfig(flag("-p", "--allow-private-address", { description: message`Allow private IP addresses in the URL.` }), {
11
8
  context: configContext,
@@ -28,6 +25,5 @@ const webFingerCommand = command("webfinger", merge("Network options", object({
28
25
 
29
26
  The argument can be multiple.`
30
27
  });
31
-
32
28
  //#endregion
33
- export { webFingerCommand };
29
+ export { webFingerCommand };
@@ -1,8 +1,5 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  import { message } from "@optique/core";
5
-
6
3
  //#region src/webfinger/error.ts
7
4
  /**
8
5
  * Generates a user-friendly error message based on the type of error
@@ -42,6 +39,5 @@ var NotFoundError = class extends Error {
42
39
  throw this;
43
40
  }
44
41
  };
45
-
46
42
  //#endregion
47
- export { InvalidHandleError, NotFoundError, getErrorMessage };
43
+ export { InvalidHandleError, NotFoundError, getErrorMessage };
@@ -1,12 +1,8 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
1
+ import "@js-temporal/polyfill";
4
2
  import { InvalidHandleError } from "./error.js";
5
3
  import { toAcctUrl } from "@fedify/vocab";
6
4
  import { getLogger } from "@logtape/logtape";
7
-
8
- //#region src/webfinger/lib.ts
9
- const logger = getLogger([
5
+ getLogger([
10
6
  "fedify",
11
7
  "cli",
12
8
  "webfinger"
@@ -40,6 +36,5 @@ function convertUrlIfHandle(handleOrUrl) {
40
36
  function convertHandleToUrl(handle) {
41
37
  return toAcctUrl(handle) ?? new InvalidHandleError(handle).throw();
42
38
  }
43
-
44
39
  //#endregion
45
- export { convertUrlIfHandle };
40
+ export { convertUrlIfHandle };
@@ -1,5 +1,4 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
4
- import { runWebFinger } from "./action.js";
5
- import { webFingerCommand } from "./command.js";
1
+ import "@js-temporal/polyfill";
2
+ import "./action.js";
3
+ import "./command.js";
4
+ export {};