@fedify/cli 1.8.12 → 2.0.0-dev.1757
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 +72 -0
- package/dist/cache.js +17 -0
- package/dist/deno.js +72 -0
- package/dist/docloader.js +52 -0
- package/dist/globals.js +49 -0
- package/dist/imagerenderer.js +105 -0
- package/dist/inbox/rendercode.js +57 -0
- package/dist/inbox/view.js +508 -0
- package/dist/inbox.js +315 -0
- package/dist/init/action/configs.js +81 -0
- package/dist/init/action/deps.js +52 -0
- package/dist/init/action/dir.js +16 -0
- package/dist/init/action/env.js +13 -0
- package/dist/init/action/install.js +22 -0
- package/dist/init/action/mod.js +39 -0
- package/dist/init/action/notice.js +62 -0
- package/dist/init/action/patch.js +141 -0
- package/dist/init/action/precommand.js +23 -0
- package/dist/init/action/recommend.js +24 -0
- package/dist/init/action/set.js +31 -0
- package/dist/init/action/templates.js +57 -0
- package/dist/init/action/utils.js +50 -0
- package/dist/init/ask/dir.js +82 -0
- package/dist/init/ask/kv.js +33 -0
- package/dist/init/ask/mod.js +16 -0
- package/dist/init/ask/mq.js +33 -0
- package/dist/init/ask/pm.js +49 -0
- package/dist/init/ask/wf.js +29 -0
- package/dist/init/command.js +25 -0
- package/dist/init/const.js +31 -0
- package/dist/init/json/biome.js +24 -0
- package/dist/init/json/kv.js +53 -0
- package/dist/init/json/mq.js +72 -0
- package/dist/init/json/pm.js +44 -0
- package/dist/init/json/rt.js +39 -0
- package/dist/init/json/vscode-settings-for-deno.js +53 -0
- package/dist/init/json/vscode-settings.js +49 -0
- package/dist/init/lib.js +129 -0
- package/dist/init/mod.js +5 -0
- package/dist/init/webframeworks.js +133 -0
- package/dist/kv.bun.js +17 -0
- package/dist/kv.node.js +17 -0
- package/dist/log.js +52 -0
- package/dist/lookup.js +287 -0
- package/dist/mod.js +34 -0
- package/dist/nodeinfo.js +261 -0
- package/dist/table.js +24 -0
- package/dist/tempserver.js +71 -0
- package/dist/tunnel.js +21 -0
- package/dist/utils.js +67 -0
- package/dist/webfinger/action.js +44 -0
- package/dist/webfinger/command.js +20 -0
- package/dist/webfinger/error.js +47 -0
- package/dist/webfinger/lib.js +45 -0
- package/dist/webfinger/mod.js +5 -0
- package/package.json +64 -24
- package/scripts/pack.ts +64 -0
- package/src/cache.ts +17 -0
- package/src/docloader.ts +67 -0
- package/src/globals.ts +43 -0
- package/src/imagerenderer.ts +149 -0
- package/src/inbox/entry.ts +10 -0
- package/src/inbox/rendercode.ts +68 -0
- package/src/inbox/view.tsx +598 -0
- package/src/inbox.tsx +535 -0
- package/src/init/action/configs.ts +88 -0
- package/src/init/action/deps.ts +93 -0
- package/src/init/action/dir.ts +11 -0
- package/src/init/action/env.ts +14 -0
- package/src/init/action/install.ts +59 -0
- package/src/init/action/mod.ts +66 -0
- package/src/init/action/notice.ts +101 -0
- package/src/init/action/patch.ts +212 -0
- package/src/init/action/precommand.ts +22 -0
- package/src/init/action/recommend.ts +38 -0
- package/src/init/action/set.ts +78 -0
- package/src/init/action/templates.ts +95 -0
- package/src/init/action/utils.ts +64 -0
- package/src/init/ask/dir.ts +98 -0
- package/src/init/ask/kv.ts +39 -0
- package/src/init/ask/mod.ts +23 -0
- package/src/init/ask/mq.ts +37 -0
- package/src/init/ask/pm.ts +58 -0
- package/src/init/ask/wf.ts +27 -0
- package/src/init/command.ts +64 -0
- package/src/init/const.ts +4 -0
- package/src/init/json/biome.json +17 -0
- package/src/init/json/kv.json +39 -0
- package/src/init/json/mq.json +95 -0
- package/src/init/json/pm.json +47 -0
- package/src/init/json/rt.json +42 -0
- package/src/init/json/vscode-settings-for-deno.json +43 -0
- package/src/init/json/vscode-settings.json +41 -0
- package/src/init/lib.ts +220 -0
- package/src/init/mod.ts +2 -0
- package/src/init/templates/defaults/federation.ts.tpl +23 -0
- package/src/init/templates/defaults/logging.ts.tpl +23 -0
- package/src/init/templates/express/app.ts.tpl +16 -0
- package/src/init/templates/express/index.ts.tpl +6 -0
- package/src/init/templates/hono/app.tsx.tpl +14 -0
- package/src/init/templates/hono/index/bun.ts.tpl +10 -0
- package/src/init/templates/hono/index/deno.ts.tpl +13 -0
- package/src/init/templates/hono/index/node.ts.tpl +14 -0
- package/src/init/templates/next/middleware.ts.tpl +45 -0
- package/src/init/templates/nitro/nitro.config.ts.tpl +5 -0
- package/src/init/templates/nitro/server/error.ts.tpl +3 -0
- package/src/init/templates/nitro/server/middleware/federation.ts.tpl +8 -0
- package/src/init/types.ts +88 -0
- package/src/init/webframeworks.ts +151 -0
- package/src/kv.bun.ts +12 -0
- package/src/kv.node.ts +11 -0
- package/src/log.ts +64 -0
- package/src/lookup.test.ts +182 -0
- package/src/lookup.ts +558 -0
- package/src/mod.ts +45 -0
- package/src/nodeinfo.test.ts +229 -0
- package/src/nodeinfo.ts +447 -0
- package/src/table.ts +17 -0
- package/src/tempserver.ts +87 -0
- package/src/tunnel.ts +32 -0
- package/src/utils.ts +136 -0
- package/src/webfinger/action.ts +50 -0
- package/src/webfinger/command.ts +59 -0
- package/src/webfinger/error.ts +47 -0
- package/src/webfinger/lib.ts +37 -0
- package/src/webfinger/mod.test.ts +79 -0
- package/src/webfinger/mod.ts +2 -0
- package/tsdown.config.ts +24 -0
- package/src/install.mjs +0 -189
- package/src/run.mjs +0 -22
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { encodeBase64 } from "byte-encodings/base64";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import process from "node:process";
|
|
6
|
+
import { Jimp } from "./nodeinfo.ts";
|
|
7
|
+
|
|
8
|
+
export type TerminalType = "kitty" | "iterm2" | "none";
|
|
9
|
+
|
|
10
|
+
const KITTY_IDENTIFIERS: string[] = [
|
|
11
|
+
"kitty",
|
|
12
|
+
"wezterm",
|
|
13
|
+
"konsole",
|
|
14
|
+
"warp",
|
|
15
|
+
"wayst",
|
|
16
|
+
"st",
|
|
17
|
+
"ghostty",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
type KittyCommand = Record<string, string | number>;
|
|
21
|
+
|
|
22
|
+
export function detectTerminalCapabilities(): TerminalType {
|
|
23
|
+
const termProgram = (process.env.TERM_PROGRAM || "").toLowerCase();
|
|
24
|
+
|
|
25
|
+
if (KITTY_IDENTIFIERS.includes(termProgram)) return "kitty";
|
|
26
|
+
|
|
27
|
+
if (termProgram === "iterm.app") return "iterm2";
|
|
28
|
+
|
|
29
|
+
return "none";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function serializeGrCommand(
|
|
33
|
+
cmd: KittyCommand,
|
|
34
|
+
payload?: string,
|
|
35
|
+
): Uint8Array {
|
|
36
|
+
const cmdString = Object.entries(cmd)
|
|
37
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
38
|
+
.join(",");
|
|
39
|
+
|
|
40
|
+
const encoder = new TextEncoder();
|
|
41
|
+
const parts: Uint8Array[] = [];
|
|
42
|
+
|
|
43
|
+
parts.push(encoder.encode("\x1b_G"));
|
|
44
|
+
parts.push(encoder.encode(cmdString));
|
|
45
|
+
|
|
46
|
+
if (payload) {
|
|
47
|
+
parts.push(encoder.encode(";"));
|
|
48
|
+
parts.push(encoder.encode(payload));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
parts.push(encoder.encode("\x1b\\"));
|
|
52
|
+
|
|
53
|
+
const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
|
|
54
|
+
const result = new Uint8Array(totalLength);
|
|
55
|
+
let offset = 0;
|
|
56
|
+
|
|
57
|
+
for (const part of parts) {
|
|
58
|
+
result.set(part, offset);
|
|
59
|
+
offset += part.length;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function renderImageKitty(
|
|
66
|
+
imagePath: string,
|
|
67
|
+
cmd: KittyCommand,
|
|
68
|
+
): Promise<void> {
|
|
69
|
+
const imageData = await fs.readFile(imagePath);
|
|
70
|
+
const base64Data = encodeBase64(imageData);
|
|
71
|
+
let remaining = base64Data;
|
|
72
|
+
let isFirst = true;
|
|
73
|
+
|
|
74
|
+
while (remaining.length > 0) {
|
|
75
|
+
const chunk = remaining.slice(0, 4096);
|
|
76
|
+
remaining = remaining.slice(4096);
|
|
77
|
+
|
|
78
|
+
const chunkCmd = {
|
|
79
|
+
...(isFirst ? cmd : {}),
|
|
80
|
+
m: remaining.length > 0 ? 1 : 0,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const command = serializeGrCommand(chunkCmd, chunk);
|
|
84
|
+
|
|
85
|
+
process.stderr.write(command);
|
|
86
|
+
|
|
87
|
+
isFirst = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function renderImageITerm2(
|
|
92
|
+
imagePath: string,
|
|
93
|
+
): Promise<void> {
|
|
94
|
+
const imageData = await fs.readFile(imagePath);
|
|
95
|
+
const base64Data = encodeBase64(imageData);
|
|
96
|
+
|
|
97
|
+
const encoder = new TextEncoder();
|
|
98
|
+
const command = encoder.encode(
|
|
99
|
+
`\x1b]1337;File=inline=1preserveAspectRatio=1:${base64Data}\x07\n`,
|
|
100
|
+
);
|
|
101
|
+
process.stderr.write(command);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export async function downloadImage(url: string): Promise<string | null> {
|
|
105
|
+
try {
|
|
106
|
+
const response = await fetch(url);
|
|
107
|
+
const imageData = new Uint8Array(await response.arrayBuffer());
|
|
108
|
+
const extension = new URL(url).pathname.split(".").pop() || "jpg";
|
|
109
|
+
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "fedify"));
|
|
110
|
+
const tempPath = path.join(tempDir, `image.${extension}`);
|
|
111
|
+
|
|
112
|
+
await fs.writeFile(tempPath, imageData);
|
|
113
|
+
|
|
114
|
+
return tempPath;
|
|
115
|
+
} catch (_error) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function renderImages(
|
|
121
|
+
imageUrls: URL[],
|
|
122
|
+
): Promise<void> {
|
|
123
|
+
const graphicsProtocol = detectTerminalCapabilities();
|
|
124
|
+
for (const url of imageUrls) {
|
|
125
|
+
const tempPath = await downloadImage(url.href);
|
|
126
|
+
if (!tempPath) continue;
|
|
127
|
+
|
|
128
|
+
const convertedImagePath: `${string}.png` = `${tempPath}.converted.png`;
|
|
129
|
+
const image = await Jimp.read(tempPath);
|
|
130
|
+
await image.write(convertedImagePath);
|
|
131
|
+
await fs.rm(tempPath);
|
|
132
|
+
|
|
133
|
+
console.error(); // clear the line before rendering image
|
|
134
|
+
|
|
135
|
+
if (graphicsProtocol === "kitty") {
|
|
136
|
+
await renderImageKitty(convertedImagePath, {
|
|
137
|
+
a: "T",
|
|
138
|
+
f: 100, // specify the image format is png
|
|
139
|
+
});
|
|
140
|
+
} else if (graphicsProtocol === "iterm2") {
|
|
141
|
+
await renderImageITerm2(convertedImagePath);
|
|
142
|
+
} else {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
console.error(); // clear the line after rendering image
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// cSpell: ignore ghostty iterm konsole magick wezterm wayst
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Activity } from "@fedify/fedify";
|
|
2
|
+
import { getStatusText } from "@poppanator/http-constants";
|
|
3
|
+
import { getContextLoader } from "../docloader.ts";
|
|
4
|
+
|
|
5
|
+
export async function renderRequest(request: Request): Promise<string> {
|
|
6
|
+
// @ts-ignore: Work around `deno publish --dry-run` bug
|
|
7
|
+
request = request.clone();
|
|
8
|
+
const url = new URL(request.url);
|
|
9
|
+
let code = `${request.method} ${url.pathname + url.search}\n`;
|
|
10
|
+
for (const [key, value] of request.headers.entries()) {
|
|
11
|
+
code += `${capitalize(key)}: ${value}\n`;
|
|
12
|
+
}
|
|
13
|
+
let body: string;
|
|
14
|
+
try {
|
|
15
|
+
body = await request.text();
|
|
16
|
+
} catch (_) {
|
|
17
|
+
body = "[Failed to decode body; it may be binary.]";
|
|
18
|
+
}
|
|
19
|
+
code += `\n${body}`;
|
|
20
|
+
return code;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function renderResponse(response: Response): Promise<string> {
|
|
24
|
+
response = response.clone();
|
|
25
|
+
let code = `${response.status} ${
|
|
26
|
+
response.statusText === ""
|
|
27
|
+
? getStatusText(response.status)
|
|
28
|
+
: response.statusText
|
|
29
|
+
}\n`;
|
|
30
|
+
for (const [key, value] of response.headers.entries()) {
|
|
31
|
+
code += `${capitalize(key)}: ${value}\n`;
|
|
32
|
+
}
|
|
33
|
+
let body: string;
|
|
34
|
+
try {
|
|
35
|
+
body = await response.text();
|
|
36
|
+
} catch (_) {
|
|
37
|
+
body = "[Failed to decode body; it may be binary.]";
|
|
38
|
+
}
|
|
39
|
+
code += `\n${body}`;
|
|
40
|
+
return code;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export async function renderRawActivity(request: Request): Promise<string> {
|
|
44
|
+
// @ts-ignore: Work around `deno publish --dry-run` bug
|
|
45
|
+
request = request.clone();
|
|
46
|
+
try {
|
|
47
|
+
const activity = await request.json();
|
|
48
|
+
return JSON.stringify(activity, null, 2);
|
|
49
|
+
} catch {
|
|
50
|
+
return "[Failed to decode body; it may not be JSON.]";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function renderActivity(
|
|
55
|
+
activity: Activity,
|
|
56
|
+
expand: boolean = false,
|
|
57
|
+
): Promise<string> {
|
|
58
|
+
const contextLoader = await getContextLoader();
|
|
59
|
+
const jsonLd = await activity.toJsonLd({
|
|
60
|
+
contextLoader,
|
|
61
|
+
format: expand ? "expand" : "compact",
|
|
62
|
+
});
|
|
63
|
+
return JSON.stringify(jsonLd, null, 2);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function capitalize(name: string): string {
|
|
67
|
+
return name.replace(/(^|-)./g, (match) => match.toUpperCase());
|
|
68
|
+
}
|