@fedify/cli 2.0.0-pr.469.1873 → 2.0.0-pr.474.1879

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/deno.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/cli",
3
- "version": "2.0.0-pr.469.1873+ebbd8642",
3
+ "version": "2.0.0-pr.474.1879+be9e2989",
4
4
  "license": "MIT",
5
5
  "exports": "./src/mod.ts",
6
6
  "imports": {
package/dist/deno.js CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  //#region deno.json
5
5
  var name = "@fedify/cli";
6
- var version = "2.0.0-pr.469.1873+ebbd8642";
6
+ var version = "2.0.0-pr.474.1879+be9e2989";
7
7
  var license = "MIT";
8
8
  var exports = "./src/mod.ts";
9
9
  var imports = {
package/dist/inbox.js CHANGED
@@ -30,7 +30,8 @@ const inboxCommand = command("inbox", merge(object("Inbox options", {
30
30
  acceptFollow: optional(multiple(option("-a", "--accept-follow", string({ metavar: "URI" }), { description: message`Accept follow requests from the given actor. The argument can be either an actor URI or a handle, or a wildcard (${"*"}). Can be specified multiple times. If a wildcard is specified, all follow requests will be accepted.` }))),
31
31
  noTunnel: option("-T", "--no-tunnel", { description: message`Do not tunnel the ephemeral ActivityPub server to the public Internet.` }),
32
32
  actorName: withDefault(option("--actor-name", string({ metavar: "NAME" }), { description: message`Customize the actor display name.` }), "Fedify Ephemeral Inbox"),
33
- actorSummary: withDefault(option("--actor-summary", string({ metavar: "SUMMARY" }), { description: message`Customize the actor description.` }), "An ephemeral ActivityPub inbox for testing purposes.")
33
+ actorSummary: withDefault(option("--actor-summary", string({ metavar: "SUMMARY" }), { description: message`Customize the actor description.` }), "An ephemeral ActivityPub inbox for testing purposes."),
34
+ authorizedFetch: option("-A", "--authorized-fetch", { description: message`Require HTTP Signatures for all incoming requests. Returns 401 for unsigned requests.` })
34
35
  }), debugOption), {
35
36
  brief: message`Run an ephemeral ActivityPub inbox server.`,
36
37
  description: message`Spins up an ephemeral server that serves the ActivityPub inbox with an one-time actor, through a short-lived public DNS with HTTPS. You can monitor the incoming activities in real-time.`
@@ -38,7 +39,8 @@ const inboxCommand = command("inbox", merge(object("Inbox options", {
38
39
  async function runInbox(command$1) {
39
40
  const fetch = createFetchHandler({
40
41
  actorName: command$1.actorName,
41
- actorSummary: command$1.actorSummary
42
+ actorSummary: command$1.actorSummary,
43
+ requireHttpSignature: command$1.authorizedFetch
42
44
  });
43
45
  const sendDeleteToPeers = createSendDeleteToPeers({
44
46
  actorName: command$1.actorName,
@@ -300,6 +302,7 @@ function createFetchHandler(actorOptions) {
300
302
  actorName: actorOptions.actorName,
301
303
  actorSummary: actorOptions.actorSummary
302
304
  },
305
+ requireHttpSignature: actorOptions.requireHttpSignature,
303
306
  onNotAcceptable: app.fetch.bind(app),
304
307
  onNotFound: app.fetch.bind(app),
305
308
  onUnauthorized: app.fetch.bind(app)
@@ -2,7 +2,7 @@
2
2
  import { Temporal } from "@js-temporal/polyfill";
3
3
 
4
4
  import { colors } from "../../utils.js";
5
- import { message, text } from "@optique/core";
5
+ import { message } from "@optique/core";
6
6
  import { print, printError } from "@optique/run";
7
7
  import { flow } from "es-toolkit";
8
8
 
@@ -45,15 +45,11 @@ function displayFile(path$1, content, emoji = "📄") {
45
45
  }
46
46
  const noticeConfigEnv = () => printMessage`Note that you probably want to edit the ${".env"} file.
47
47
  It currently contains the following values:\n`;
48
- const noticeEnvKeyValue = ([key, value]) => {
49
- printMessage`${text(` ${key}='${value}'`)}`;
50
- };
48
+ const noticeEnvKeyValue = ([key, value]) => printMessage` ${key}=${value}`;
51
49
  function noticeHowToRun({ initializer: { instruction, federationFile } }) {
52
- print(message`
53
- ${instruction}
54
-
55
- Start by editing the ${federationFile} file to define your federation!
56
- `);
50
+ printMessage`${instruction}`;
51
+ printMessage`Start by editing the ${federationFile} file to define your federation!
52
+ `;
57
53
  }
58
54
  function noticeErrorWhileAddDeps(command$1) {
59
55
  return (error) => {
@@ -31,7 +31,7 @@ const recommendPatchFiles = (data) => pipe(data, set("files", getFiles), set("js
31
31
  * @returns A record of file paths to their string content
32
32
  */
33
33
  const getFiles = (data) => ({
34
- [data.initializer.federationFile.toString()]: loadFederation({
34
+ [data.initializer.federationFile]: loadFederation({
35
35
  imports: getImports(data),
36
36
  ...data
37
37
  }),
package/dist/init/lib.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { Temporal } from "@js-temporal/polyfill";
3
3
 
4
4
  import deno_default from "../deno.js";
5
- import { isNotFoundError, runSubCommand } from "../utils.js";
5
+ import { colors, isNotFoundError, runSubCommand } from "../utils.js";
6
6
  import kv_default from "./json/kv.js";
7
7
  import mq_default from "./json/mq.js";
8
8
  import pm_default from "./json/pm.js";
@@ -10,7 +10,6 @@ import rt_default from "./json/rt.js";
10
10
  import webframeworks_default from "./webframeworks.js";
11
11
  import { dirname, join } from "node:path";
12
12
  import { mkdir, readdir, writeFile } from "node:fs/promises";
13
- import { commandLine, message } from "@optique/core/message";
14
13
  import process from "node:process";
15
14
  import { getLogger } from "@logtape/logtape";
16
15
  import { entries, evolve, fromEntries, isObject, map, negate, pipe, throwIf, when } from "@fxts/core";
@@ -45,17 +44,17 @@ async function isPackageManagerAvailable(pm) {
45
44
  return false;
46
45
  }
47
46
  const readTemplate = (templatePath) => readFileSync(join(import.meta.dirname, "templates", ...(templatePath + ".tpl").split("/")), "utf8");
48
- const getInstruction = (pm) => message`
47
+ const getInstruction = (pm) => `
49
48
  To start the server, run the following command:
50
49
 
51
- ${commandLine(getDevCommand(pm))}
50
+ ${getDevCommand(pm)}
52
51
 
53
52
  Then, try look up an actor from your server:
54
53
 
55
- ${commandLine("fedify lookup http://localhost:8000/users/john")}
54
+ ${colors.bold(colors.green("fedify lookup http://localhost:8000/users/john"))}
56
55
 
57
56
  `;
58
- const getDevCommand = (pm) => pm === "deno" ? "deno task dev" : pm === "bun" ? "bun dev" : `${pm} run dev`;
57
+ const getDevCommand = (pm) => colors.bold(colors.green(pm === "deno" ? "deno task dev" : pm === "bun" ? "bun dev" : `${pm} run dev`));
59
58
  async function isCommandAvailable({ checkCommand, outputPattern }) {
60
59
  try {
61
60
  const { stdout } = await runSubCommand(checkCommand, { stdio: [
@@ -4,7 +4,6 @@
4
4
  import { replace } from "../utils.js";
5
5
  import { PACKAGE_MANAGER } from "./const.js";
6
6
  import { PACKAGE_VERSION, getInstruction, getNextInitCommand, getNitroInitCommand, readTemplate } from "./lib.js";
7
- import { message } from "@optique/core";
8
7
  import { pipe } from "@fxts/core";
9
8
 
10
9
  //#region src/init/webframeworks.ts
@@ -28,7 +27,7 @@ const webFrameworks = {
28
27
  "x-forwarded-fetch": "^0.2.0"
29
28
  },
30
29
  devDependencies: pm === "bun" ? { "@types/bun": "^1.1.6" } : {},
31
- federationFile: message`src/federation.ts`,
30
+ federationFile: "src/federation.ts",
32
31
  loggingFile: "src/logging.ts",
33
32
  files: {
34
33
  "src/app.tsx": pipe("hono/app.tsx", readTemplate, replace(/\/\* hono \*\//, pm === "deno" ? "@hono/hono" : "hono")).replace(/\/\* logger \*\//, projectName),
@@ -74,7 +73,7 @@ const webFrameworks = {
74
73
  "@types/express": "^4.17.21",
75
74
  ...pm === "bun" ? { "@types/bun": "^1.1.6" } : {}
76
75
  },
77
- federationFile: message`src/federation.ts`,
76
+ federationFile: "src/federation.ts",
78
77
  loggingFile: "src/logging.ts",
79
78
  files: {
80
79
  "src/app.ts": readTemplate("express/app.ts").replace(/\/\* logger \*\//, projectName),
@@ -103,7 +102,7 @@ const webFrameworks = {
103
102
  init: (_, pm) => ({
104
103
  command: getNitroInitCommand(pm),
105
104
  dependencies: { "@fedify/h3": PACKAGE_VERSION },
106
- federationFile: message`server/federation.ts`,
105
+ federationFile: "server/federation.ts",
107
106
  loggingFile: "server/logging.ts",
108
107
  files: {
109
108
  "server/middleware/federation.ts": readTemplate("nitro/server/middleware/federation.ts"),
@@ -121,7 +120,7 @@ const webFrameworks = {
121
120
  command: getNextInitCommand(pm),
122
121
  dependencies: { "@fedify/next": PACKAGE_VERSION },
123
122
  devDependencies: { "@types/node": "^20.11.2" },
124
- federationFile: message`federation/index.ts`,
123
+ federationFile: "federation/index.ts",
125
124
  loggingFile: "logging.ts",
126
125
  files: { "middleware.ts": readTemplate("next/middleware.ts") },
127
126
  instruction: getInstruction(pm)
package/dist/nodeinfo.js CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  import { debugOption } from "./globals.js";
5
5
  import { colors, formatObject } from "./utils.js";
6
- import { argument, command, constant, flag, merge, message, object, option, optional, or, string, text } from "@optique/core";
6
+ import { argument, command, constant, flag, merge, message, object, option, optional, or, string } from "@optique/core";
7
7
  import { print, printError } from "@optique/run";
8
8
  import process from "node:process";
9
9
  import { getNodeInfo } from "@fedify/fedify";
@@ -58,7 +58,7 @@ async function runNodeInfo(command$1) {
58
58
  process.exit(1);
59
59
  }
60
60
  spinner.succeed("NodeInfo document fetched.");
61
- print(message`${text(formatObject(nodeInfo$1, void 0, true))}`);
61
+ console.log(formatObject(nodeInfo$1, void 0, true));
62
62
  return;
63
63
  }
64
64
  const nodeInfo = await getNodeInfo(url, {
@@ -153,15 +153,15 @@ async function runNodeInfo(command$1) {
153
153
  }
154
154
  console.log(layout.join("\n"));
155
155
  }
156
- function indent(text$1, depth) {
157
- return text$1.replace(/\n/g, "\n" + " ".repeat(depth));
156
+ function indent(text, depth) {
157
+ return text.replace(/\n/g, "\n" + " ".repeat(depth));
158
158
  }
159
159
  const LINK_REGEXP = /<link((?:\s+(?:[-a-z]+)=(?:"[^"]*"|'[^']*'|[^\s]+))*)\s*\/?>/gi;
160
160
  const LINK_ATTRS_REGEXP = /(?:\s+([-a-z]+)=("[^"]*"|'[^']*'|[^\s]+))/gi;
161
161
  async function getFaviconUrl(url, userAgent) {
162
162
  const response = await fetch(url, { headers: { "User-Agent": userAgent == null ? getUserAgent() : userAgent } });
163
- const text$1 = await response.text();
164
- for (const match of text$1.matchAll(LINK_REGEXP)) {
163
+ const text = await response.text();
164
+ for (const match of text.matchAll(LINK_REGEXP)) {
165
165
  const attrs = {};
166
166
  for (const attrMatch of match[1].matchAll(LINK_ATTRS_REGEXP)) {
167
167
  const [, key, value] = attrMatch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/cli",
3
- "version": "2.0.0-pr.469.1873+ebbd8642",
3
+ "version": "2.0.0-pr.474.1879+be9e2989",
4
4
  "description": "CLI toolchain for Fedify and debugging ActivityPub",
5
5
  "keywords": [
6
6
  "fedify",
@@ -71,10 +71,10 @@
71
71
  "ora": "^8.2.0",
72
72
  "shiki": "^1.6.4",
73
73
  "srvx": "^0.8.7",
74
- "@fedify/fedify": "2.0.0-pr.469.1873+ebbd8642",
75
- "@fedify/vocab-runtime": "2.0.0-pr.469.1873+ebbd8642",
76
- "@fedify/sqlite": "2.0.0-pr.469.1873+ebbd8642",
77
- "@fedify/vocab-tools": "2.0.0-pr.469.1873+ebbd8642"
74
+ "@fedify/fedify": "2.0.0-pr.474.1879+be9e2989",
75
+ "@fedify/vocab-runtime": "2.0.0-pr.474.1879+be9e2989",
76
+ "@fedify/vocab-tools": "2.0.0-pr.474.1879+be9e2989",
77
+ "@fedify/sqlite": "2.0.0-pr.474.1879+be9e2989"
78
78
  },
79
79
  "devDependencies": {
80
80
  "@types/bun": "^1.2.23",
package/src/inbox.tsx CHANGED
@@ -103,6 +103,14 @@ export const inboxCommand = command(
103
103
  }),
104
104
  "An ephemeral ActivityPub inbox for testing purposes.",
105
105
  ),
106
+ authorizedFetch: option(
107
+ "-A",
108
+ "--authorized-fetch",
109
+ {
110
+ description:
111
+ message`Require HTTP Signatures for all incoming requests. Returns 401 for unsigned requests.`,
112
+ },
113
+ ),
106
114
  }),
107
115
  debugOption,
108
116
  ),
@@ -119,6 +127,7 @@ export async function runInbox(
119
127
  const fetch = createFetchHandler({
120
128
  actorName: command.actorName,
121
129
  actorSummary: command.actorSummary,
130
+ requireHttpSignature: command.authorizedFetch,
122
131
  });
123
132
  const sendDeleteToPeers = createSendDeleteToPeers({
124
133
  actorName: command.actorName,
@@ -499,7 +508,11 @@ app.get("/r/:idx{[0-9]+}", (c) => {
499
508
  });
500
509
 
501
510
  function createFetchHandler(
502
- actorOptions: { actorName: string; actorSummary: string },
511
+ actorOptions: {
512
+ actorName: string;
513
+ actorSummary: string;
514
+ requireHttpSignature?: boolean;
515
+ },
503
516
  ): (request: Request) => Promise<Response> {
504
517
  return async function fetch(request: Request): Promise<Response> {
505
518
  const timestamp = Temporal.Now.instant();
@@ -521,6 +534,7 @@ function createFetchHandler(
521
534
  actorName: actorOptions.actorName,
522
535
  actorSummary: actorOptions.actorSummary,
523
536
  },
537
+ requireHttpSignature: actorOptions.requireHttpSignature,
524
538
  onNotAcceptable: app.fetch.bind(app),
525
539
  onNotFound: app.fetch.bind(app),
526
540
  onUnauthorized: app.fetch.bind(app),
@@ -1,4 +1,4 @@
1
- import { message, text } from "@optique/core";
1
+ import { message } from "@optique/core";
2
2
  import { print, printError } from "@optique/run";
3
3
  import { flow } from "es-toolkit";
4
4
  import { colors, type RequiredNotNull } from "../../utils.ts";
@@ -80,18 +80,15 @@ export const noticeConfigEnv = () =>
80
80
  printMessage`Note that you probably want to edit the ${".env"} file.
81
81
  It currently contains the following values:\n`;
82
82
 
83
- export const noticeEnvKeyValue = ([key, value]: [string, string]) => {
84
- printMessage`${text(` ${key}='${value}'`)}`;
85
- };
83
+ export const noticeEnvKeyValue = ([key, value]: [string, string]) =>
84
+ printMessage` ${key}=${value}`;
86
85
 
87
86
  export function noticeHowToRun(
88
87
  { initializer: { instruction, federationFile } }: InitCommandData,
89
88
  ) {
90
- print(message`
91
- ${instruction}
92
-
93
- Start by editing the ${federationFile} file to define your federation!
94
- `);
89
+ printMessage`${instruction}`;
90
+ printMessage`Start by editing the ${federationFile} file to define your federation!
91
+ `;
95
92
  }
96
93
 
97
94
  export function noticeErrorWhileAddDeps(command: string[]) {
@@ -53,7 +53,7 @@ export const recommendPatchFiles = (data: InitCommandData) =>
53
53
  const getFiles = <
54
54
  T extends InitCommandData,
55
55
  >(data: T) => ({
56
- [data.initializer.federationFile.toString()]: loadFederation({
56
+ [data.initializer.federationFile]: loadFederation({
57
57
  imports: getImports(data),
58
58
  ...data,
59
59
  }),
package/src/init/lib.ts CHANGED
@@ -10,15 +10,13 @@ import {
10
10
  when,
11
11
  } from "@fxts/core";
12
12
  import { getLogger } from "@logtape/logtape";
13
- import type { Message } from "@optique/core";
14
- import { commandLine, message } from "@optique/core/message";
13
+ import { dirname, join as joinPath } from "node:path";
15
14
  import { toMerged } from "es-toolkit";
16
15
  import { readFileSync } from "node:fs";
17
16
  import { mkdir, readdir, writeFile } from "node:fs/promises";
18
- import { dirname, join as joinPath } from "node:path";
19
17
  import process from "node:process";
20
18
  import metadata from "../../deno.json" with { type: "json" };
21
- import { isNotFoundError, runSubCommand } from "../utils.ts";
19
+ import { colors, isNotFoundError, runSubCommand } from "../utils.ts";
22
20
  import kv from "./json/kv.json" with { type: "json" };
23
21
  import mq from "./json/mq.json" with { type: "json" };
24
22
  import pm from "./json/pm.json" with { type: "json" };
@@ -110,20 +108,31 @@ export const readTemplate: (templatePath: string) => string = (
110
108
 
111
109
  export const getInstruction: (
112
110
  packageManager: PackageManager,
113
- ) => Message = (pm) =>
114
- message`
111
+ ) => string = (pm) => `
115
112
  To start the server, run the following command:
116
113
 
117
- ${commandLine(getDevCommand(pm))}
114
+ ${getDevCommand(pm)}
118
115
 
119
116
  Then, try look up an actor from your server:
120
117
 
121
- ${commandLine("fedify lookup http://localhost:8000/users/john")}
118
+ ${
119
+ colors.bold(colors.green(
120
+ "fedify lookup http://localhost:8000/users/john",
121
+ ))
122
+ }
122
123
 
123
124
  `;
124
125
 
125
126
  const getDevCommand = (pm: PackageManager) =>
126
- pm === "deno" ? "deno task dev" : pm === "bun" ? "bun dev" : `${pm} run dev`;
127
+ colors.bold(
128
+ colors.green(
129
+ pm === "deno"
130
+ ? "deno task dev"
131
+ : pm === "bun"
132
+ ? "bun dev"
133
+ : `${pm} run dev`,
134
+ ),
135
+ );
127
136
 
128
137
  async function isCommandAvailable(
129
138
  { checkCommand, outputPattern }: {
package/src/init/types.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { Message } from "@optique/core";
2
1
  import type { RequiredNotNull } from "../utils.ts";
3
2
  import type { InitCommand } from "./command.ts";
4
3
  import type {
@@ -36,12 +35,12 @@ export interface WebFrameworkInitializer {
36
35
  command?: string[];
37
36
  dependencies?: object;
38
37
  devDependencies?: object;
39
- federationFile: Message;
38
+ federationFile: string;
40
39
  loggingFile: string;
41
40
  files?: Record<string, string>;
42
41
  compilerOptions?: Record<string, string | boolean | number | string[] | null>;
43
42
  tasks?: Record<string, string>;
44
- instruction: Message;
43
+ instruction: string;
45
44
  }
46
45
 
47
46
  export interface WebFrameworkDescription {
@@ -1,5 +1,4 @@
1
1
  import { pipe } from "@fxts/core";
2
- import { message } from "@optique/core";
3
2
  import { replace } from "../utils.ts";
4
3
  import { PACKAGE_MANAGER } from "./const.ts";
5
4
  import {
@@ -32,7 +31,7 @@ const webFrameworks: WebFrameworks = {
32
31
  "x-forwarded-fetch": "^0.2.0",
33
32
  },
34
33
  devDependencies: pm === "bun" ? { "@types/bun": "^1.1.6" } : {},
35
- federationFile: message`src/federation.ts`,
34
+ federationFile: "src/federation.ts",
36
35
  loggingFile: "src/logging.ts",
37
36
  files: {
38
37
  "src/app.tsx": pipe(
@@ -88,7 +87,7 @@ const webFrameworks: WebFrameworks = {
88
87
  "@types/express": "^4.17.21",
89
88
  ...(pm === "bun" ? { "@types/bun": "^1.1.6" } : {}),
90
89
  },
91
- federationFile: message`src/federation.ts`,
90
+ federationFile: "src/federation.ts",
92
91
  loggingFile: "src/logging.ts",
93
92
  files: {
94
93
  "src/app.ts": readTemplate("express/app.ts")
@@ -122,7 +121,7 @@ const webFrameworks: WebFrameworks = {
122
121
  init: (_, pm) => ({
123
122
  command: getNitroInitCommand(pm),
124
123
  dependencies: { "@fedify/h3": PACKAGE_VERSION },
125
- federationFile: message`server/federation.ts`,
124
+ federationFile: "server/federation.ts",
126
125
  loggingFile: "server/logging.ts",
127
126
  files: {
128
127
  "server/middleware/federation.ts": readTemplate(
@@ -142,7 +141,7 @@ const webFrameworks: WebFrameworks = {
142
141
  command: getNextInitCommand(pm),
143
142
  dependencies: { "@fedify/next": PACKAGE_VERSION },
144
143
  devDependencies: { "@types/node": "^20.11.2" },
145
- federationFile: message`federation/index.ts`,
144
+ federationFile: "federation/index.ts",
146
145
  loggingFile: "logging.ts",
147
146
  files: { "middleware.ts": readTemplate("next/middleware.ts") },
148
147
  instruction: getInstruction(pm),
package/src/nodeinfo.ts CHANGED
@@ -16,7 +16,6 @@ import {
16
16
  optional,
17
17
  or,
18
18
  string,
19
- text,
20
19
  } from "@optique/core";
21
20
  import { print, printError } from "@optique/run";
22
21
  import type { ChalkInstance } from "chalk";
@@ -112,7 +111,7 @@ export async function runNodeInfo(
112
111
  }
113
112
  spinner.succeed("NodeInfo document fetched.");
114
113
 
115
- print(message`${text(formatObject(nodeInfo, undefined, true))}`);
114
+ console.log(formatObject(nodeInfo, undefined, true));
116
115
  return;
117
116
  }
118
117
  const nodeInfo = await getNodeInfo(url, {