@fedify/cli 1.8.12 → 2.0.0-dev.1761

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.
Files changed (130) hide show
  1. package/deno.json +71 -0
  2. package/dist/cache.js +17 -0
  3. package/dist/deno.js +71 -0
  4. package/dist/docloader.js +52 -0
  5. package/dist/globals.js +49 -0
  6. package/dist/imagerenderer.js +105 -0
  7. package/dist/inbox/rendercode.js +57 -0
  8. package/dist/inbox/view.js +508 -0
  9. package/dist/inbox.js +315 -0
  10. package/dist/init/action/configs.js +81 -0
  11. package/dist/init/action/deps.js +52 -0
  12. package/dist/init/action/dir.js +16 -0
  13. package/dist/init/action/env.js +13 -0
  14. package/dist/init/action/install.js +22 -0
  15. package/dist/init/action/mod.js +39 -0
  16. package/dist/init/action/notice.js +62 -0
  17. package/dist/init/action/patch.js +141 -0
  18. package/dist/init/action/precommand.js +23 -0
  19. package/dist/init/action/recommend.js +24 -0
  20. package/dist/init/action/set.js +31 -0
  21. package/dist/init/action/templates.js +57 -0
  22. package/dist/init/action/utils.js +50 -0
  23. package/dist/init/ask/dir.js +82 -0
  24. package/dist/init/ask/kv.js +33 -0
  25. package/dist/init/ask/mod.js +16 -0
  26. package/dist/init/ask/mq.js +33 -0
  27. package/dist/init/ask/pm.js +49 -0
  28. package/dist/init/ask/wf.js +29 -0
  29. package/dist/init/command.js +25 -0
  30. package/dist/init/const.js +31 -0
  31. package/dist/init/json/biome.js +24 -0
  32. package/dist/init/json/kv.js +53 -0
  33. package/dist/init/json/mq.js +72 -0
  34. package/dist/init/json/pm.js +44 -0
  35. package/dist/init/json/rt.js +39 -0
  36. package/dist/init/json/vscode-settings-for-deno.js +53 -0
  37. package/dist/init/json/vscode-settings.js +49 -0
  38. package/dist/init/lib.js +129 -0
  39. package/dist/init/mod.js +5 -0
  40. package/dist/init/webframeworks.js +133 -0
  41. package/dist/kv.bun.js +17 -0
  42. package/dist/kv.node.js +17 -0
  43. package/dist/log.js +52 -0
  44. package/dist/lookup.js +287 -0
  45. package/dist/mod.js +34 -0
  46. package/dist/nodeinfo.js +261 -0
  47. package/dist/table.js +24 -0
  48. package/dist/tempserver.js +71 -0
  49. package/dist/tunnel.js +21 -0
  50. package/dist/utils.js +67 -0
  51. package/dist/webfinger/action.js +44 -0
  52. package/dist/webfinger/command.js +20 -0
  53. package/dist/webfinger/error.js +47 -0
  54. package/dist/webfinger/lib.js +45 -0
  55. package/dist/webfinger/mod.js +5 -0
  56. package/package.json +64 -24
  57. package/scripts/pack.ts +64 -0
  58. package/src/cache.ts +17 -0
  59. package/src/docloader.ts +67 -0
  60. package/src/globals.ts +43 -0
  61. package/src/imagerenderer.ts +149 -0
  62. package/src/inbox/entry.ts +10 -0
  63. package/src/inbox/rendercode.ts +68 -0
  64. package/src/inbox/view.tsx +598 -0
  65. package/src/inbox.tsx +535 -0
  66. package/src/init/action/configs.ts +88 -0
  67. package/src/init/action/deps.ts +93 -0
  68. package/src/init/action/dir.ts +11 -0
  69. package/src/init/action/env.ts +14 -0
  70. package/src/init/action/install.ts +59 -0
  71. package/src/init/action/mod.ts +66 -0
  72. package/src/init/action/notice.ts +101 -0
  73. package/src/init/action/patch.ts +212 -0
  74. package/src/init/action/precommand.ts +22 -0
  75. package/src/init/action/recommend.ts +38 -0
  76. package/src/init/action/set.ts +78 -0
  77. package/src/init/action/templates.ts +95 -0
  78. package/src/init/action/utils.ts +64 -0
  79. package/src/init/ask/dir.ts +98 -0
  80. package/src/init/ask/kv.ts +39 -0
  81. package/src/init/ask/mod.ts +23 -0
  82. package/src/init/ask/mq.ts +37 -0
  83. package/src/init/ask/pm.ts +58 -0
  84. package/src/init/ask/wf.ts +27 -0
  85. package/src/init/command.ts +64 -0
  86. package/src/init/const.ts +4 -0
  87. package/src/init/json/biome.json +17 -0
  88. package/src/init/json/kv.json +39 -0
  89. package/src/init/json/mq.json +95 -0
  90. package/src/init/json/pm.json +47 -0
  91. package/src/init/json/rt.json +42 -0
  92. package/src/init/json/vscode-settings-for-deno.json +43 -0
  93. package/src/init/json/vscode-settings.json +41 -0
  94. package/src/init/lib.ts +220 -0
  95. package/src/init/mod.ts +2 -0
  96. package/src/init/templates/defaults/federation.ts.tpl +23 -0
  97. package/src/init/templates/defaults/logging.ts.tpl +23 -0
  98. package/src/init/templates/express/app.ts.tpl +16 -0
  99. package/src/init/templates/express/index.ts.tpl +6 -0
  100. package/src/init/templates/hono/app.tsx.tpl +14 -0
  101. package/src/init/templates/hono/index/bun.ts.tpl +10 -0
  102. package/src/init/templates/hono/index/deno.ts.tpl +13 -0
  103. package/src/init/templates/hono/index/node.ts.tpl +14 -0
  104. package/src/init/templates/next/middleware.ts.tpl +45 -0
  105. package/src/init/templates/nitro/nitro.config.ts.tpl +5 -0
  106. package/src/init/templates/nitro/server/error.ts.tpl +3 -0
  107. package/src/init/templates/nitro/server/middleware/federation.ts.tpl +8 -0
  108. package/src/init/types.ts +88 -0
  109. package/src/init/webframeworks.ts +151 -0
  110. package/src/kv.bun.ts +12 -0
  111. package/src/kv.node.ts +11 -0
  112. package/src/log.ts +64 -0
  113. package/src/lookup.test.ts +182 -0
  114. package/src/lookup.ts +558 -0
  115. package/src/mod.ts +45 -0
  116. package/src/nodeinfo.test.ts +229 -0
  117. package/src/nodeinfo.ts +447 -0
  118. package/src/table.ts +17 -0
  119. package/src/tempserver.ts +87 -0
  120. package/src/tunnel.ts +32 -0
  121. package/src/utils.ts +136 -0
  122. package/src/webfinger/action.ts +50 -0
  123. package/src/webfinger/command.ts +59 -0
  124. package/src/webfinger/error.ts +47 -0
  125. package/src/webfinger/lib.ts +37 -0
  126. package/src/webfinger/mod.test.ts +79 -0
  127. package/src/webfinger/mod.ts +2 -0
  128. package/tsdown.config.ts +24 -0
  129. package/src/install.mjs +0 -189
  130. package/src/run.mjs +0 -22
@@ -0,0 +1,47 @@
1
+ {
2
+ "deno": {
3
+ "label": "deno",
4
+ "checkCommand": [
5
+ "deno",
6
+ "--version"
7
+ ],
8
+ "outputPattern": "^deno\\s+\\d+\\.\\d+\\.\\d+\\b",
9
+ "installUrl": "https://docs.deno.com/runtime/getting_started/installation"
10
+ },
11
+ "bun": {
12
+ "label": "bun",
13
+ "checkCommand": [
14
+ "bun",
15
+ "--version"
16
+ ],
17
+ "outputPattern": "^\\d+\\.\\d+\\.\\d+$",
18
+ "installUrl": "https://bun.sh/docs/installation"
19
+ },
20
+ "npm": {
21
+ "label": "npm",
22
+ "checkCommand": [
23
+ "npm",
24
+ "--version"
25
+ ],
26
+ "outputPattern": "^\\d+\\.\\d+\\.\\d+$",
27
+ "installUrl": "https://docs.npmjs.com/downloading-and-installing-node-js-and-npm"
28
+ },
29
+ "yarn": {
30
+ "label": "Yarn",
31
+ "checkCommand": [
32
+ "yarn",
33
+ "--version"
34
+ ],
35
+ "outputPattern": "^\\d+\\.\\d+\\.\\d+$",
36
+ "installUrl": "https://classic.yarnpkg.com/en/docs/install/#windows-stable"
37
+ },
38
+ "pnpm": {
39
+ "label": "pnpm",
40
+ "checkCommand": [
41
+ "pnpm",
42
+ "--version"
43
+ ],
44
+ "outputPattern": "^\\d+\\.\\d+\\.\\d+$",
45
+ "installUrl": "https://pnpm.io/installation"
46
+ }
47
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "deno": {
3
+ "label": "Deno",
4
+ "checkCommand": [
5
+ "deno",
6
+ "--version"
7
+ ],
8
+ "outputPattern": "^deno\\s+\\d+\\.\\d+\\.\\d+\\b"
9
+ },
10
+ "bun": {
11
+ "label": "Bun",
12
+ "checkCommand": [
13
+ "bun",
14
+ "--version"
15
+ ],
16
+ "outputPattern": "^\\d+\\.\\d+\\.\\d+$"
17
+ },
18
+ "pnpm": {
19
+ "label": "Node.js",
20
+ "checkCommand": [
21
+ "node",
22
+ "--version"
23
+ ],
24
+ "outputPattern": "^v\\d+\\.\\d+\\.\\d+$"
25
+ },
26
+ "yarn": {
27
+ "label": "Node.js",
28
+ "checkCommand": [
29
+ "node",
30
+ "--version"
31
+ ],
32
+ "outputPattern": "^v\\d+\\.\\d+\\.\\d+$"
33
+ },
34
+ "npm": {
35
+ "label": "Node.js",
36
+ "checkCommand": [
37
+ "node",
38
+ "--version"
39
+ ],
40
+ "outputPattern": "^v\\d+\\.\\d+\\.\\d+$"
41
+ }
42
+ }
@@ -0,0 +1,43 @@
1
+ {
2
+ "deno.enable": true,
3
+ "deno.unstable": true,
4
+ "editor.detectIndentation": false,
5
+ "editor.indentSize": 2,
6
+ "editor.insertSpaces": true,
7
+ "[javascript]": {
8
+ "editor.defaultFormatter": "denoland.vscode-deno",
9
+ "editor.formatOnSave": true,
10
+ "editor.codeActionsOnSave": {
11
+ "source.sortImports": "always"
12
+ }
13
+ },
14
+ "[javascriptreact]": {
15
+ "editor.defaultFormatter": "denoland.vscode-deno",
16
+ "editor.formatOnSave": true,
17
+ "editor.codeActionsOnSave": {
18
+ "source.sortImports": "always"
19
+ }
20
+ },
21
+ "[json]": {
22
+ "editor.defaultFormatter": "vscode.json-language-features",
23
+ "editor.formatOnSave": true
24
+ },
25
+ "[jsonc]": {
26
+ "editor.defaultFormatter": "vscode.json-language-features",
27
+ "editor.formatOnSave": true
28
+ },
29
+ "[typescript]": {
30
+ "editor.defaultFormatter": "denoland.vscode-deno",
31
+ "editor.formatOnSave": true,
32
+ "editor.codeActionsOnSave": {
33
+ "source.sortImports": "always"
34
+ }
35
+ },
36
+ "[typescriptreact]": {
37
+ "editor.defaultFormatter": "denoland.vscode-deno",
38
+ "editor.formatOnSave": true,
39
+ "editor.codeActionsOnSave": {
40
+ "source.sortImports": "always"
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "editor.detectIndentation": false,
3
+ "editor.indentSize": 2,
4
+ "editor.insertSpaces": true,
5
+ "[javascript]": {
6
+ "editor.defaultFormatter": "biomejs.biome",
7
+ "editor.formatOnSave": true,
8
+ "editor.codeActionsOnSave": {
9
+ "source.organizeImports.biome": "always"
10
+ }
11
+ },
12
+ "[javascriptreact]": {
13
+ "editor.defaultFormatter": "biomejs.biome",
14
+ "editor.formatOnSave": true,
15
+ "editor.codeActionsOnSave": {
16
+ "source.organizeImports.biome": "always"
17
+ }
18
+ },
19
+ "[json]": {
20
+ "editor.defaultFormatter": "biomejs.biome",
21
+ "editor.formatOnSave": true
22
+ },
23
+ "[jsonc]": {
24
+ "editor.defaultFormatter": "biomejs.biome",
25
+ "editor.formatOnSave": true
26
+ },
27
+ "[typescript]": {
28
+ "editor.defaultFormatter": "biomejs.biome",
29
+ "editor.formatOnSave": true,
30
+ "editor.codeActionsOnSave": {
31
+ "source.organizeImports.biome": "always"
32
+ }
33
+ },
34
+ "[typescriptreact]": {
35
+ "editor.defaultFormatter": "biomejs.biome",
36
+ "editor.formatOnSave": true,
37
+ "editor.codeActionsOnSave": {
38
+ "source.organizeImports.biome": "always"
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,220 @@
1
+ import {
2
+ entries,
3
+ evolve,
4
+ fromEntries,
5
+ isObject,
6
+ map,
7
+ negate,
8
+ pipe,
9
+ throwIf,
10
+ when,
11
+ } from "@fxts/core";
12
+ import { getLogger } from "@logtape/logtape";
13
+ import { dirname, join as joinPath } from "node:path";
14
+ import { toMerged } from "es-toolkit";
15
+ import { readFileSync } from "node:fs";
16
+ import { mkdir, readdir, writeFile } from "node:fs/promises";
17
+ import process from "node:process";
18
+ import metadata from "../../deno.json" with { type: "json" };
19
+ import { colors, isNotFoundError, runSubCommand } from "../utils.ts";
20
+ import kv from "./json/kv.json" with { type: "json" };
21
+ import mq from "./json/mq.json" with { type: "json" };
22
+ import pm from "./json/pm.json" with { type: "json" };
23
+ import rt from "./json/rt.json" with { type: "json" };
24
+ import type {
25
+ KvStores,
26
+ MessageQueues,
27
+ PackageManager,
28
+ PackageManagers,
29
+ Runtimes,
30
+ } from "./types.ts";
31
+ import webFrameworks from "./webframeworks.ts";
32
+
33
+ export const PACKAGE_VERSION = metadata.version;
34
+ export const logger = getLogger(["fedify", "cli", "init"]);
35
+
36
+ const addFedifyDeps = <T extends object>(json: T): T =>
37
+ Object.fromEntries(
38
+ Object.entries(json).map(([key, value]) => [
39
+ key,
40
+ toMerged(value, {
41
+ dependencies: {
42
+ [`@fedify/${key}`]: PACKAGE_VERSION,
43
+ },
44
+ }),
45
+ ]),
46
+ ) as T;
47
+ export const kvStores = addFedifyDeps(kv as KvStores);
48
+ export const messageQueues = addFedifyDeps(mq as MessageQueues);
49
+ const toRegExp = (str: string): RegExp => new RegExp(str);
50
+ const convertPattern = <K extends string, T extends { outputPattern: string }>(
51
+ obj: Record<K, T>,
52
+ ): Record<K, Omit<T, "outputPattern"> & { outputPattern: RegExp }> =>
53
+ pipe(
54
+ obj,
55
+ entries as (obj: Record<K, T>) => Generator<[K, T]>,
56
+ map(([key, value]: [K, T]) =>
57
+ [key, evolve({ outputPattern: toRegExp })(value)] as const
58
+ ),
59
+ fromEntries,
60
+ ) as Record<K, Omit<T, "outputPattern"> & { outputPattern: RegExp }>;
61
+ const packageManagers = convertPattern(pm) as PackageManagers;
62
+ const runtimes = convertPattern(rt) as Runtimes;
63
+
64
+ export const getLabel = (name: string) =>
65
+ pipe(
66
+ name,
67
+ whenHasLabel(webFrameworks),
68
+ whenHasLabel(packageManagers),
69
+ whenHasLabel(messageQueues),
70
+ whenHasLabel(kvStores),
71
+ whenHasLabel(runtimes),
72
+ );
73
+ const whenHasLabel = <T extends Record<string, { label: string }>>(desc: T) =>
74
+ when((name: string) => name in desc, (name) => desc[name as keyof T].label);
75
+
76
+ export const getInstallUrl = (pm: PackageManager) =>
77
+ packageManagers[pm].installUrl;
78
+
79
+ export async function isPackageManagerAvailable(
80
+ pm: PackageManager,
81
+ ): Promise<boolean> {
82
+ if (await isCommandAvailable(packageManagers[pm])) return true;
83
+ if (process.platform !== "win32") return false;
84
+ const cmd: [string, ...string[]] = [
85
+ packageManagers[pm].checkCommand[0] + ".cmd",
86
+ ...packageManagers[pm].checkCommand.slice(1),
87
+ ];
88
+ if (
89
+ await isCommandAvailable({
90
+ ...packageManagers[pm],
91
+ checkCommand: cmd,
92
+ })
93
+ ) return true;
94
+ return false;
95
+ }
96
+
97
+ export const readTemplate: (templatePath: string) => string = (
98
+ templatePath,
99
+ ) =>
100
+ readFileSync(
101
+ joinPath(
102
+ import.meta.dirname!,
103
+ "templates",
104
+ ...(templatePath + ".tpl").split("/"),
105
+ ),
106
+ "utf8",
107
+ );
108
+
109
+ export const getInstruction: (
110
+ packageManager: PackageManager,
111
+ ) => string = (pm) => `
112
+ To start the server, run the following command:
113
+
114
+ ${getDevCommand(pm)}
115
+
116
+ Then, try look up an actor from your server:
117
+
118
+ ${
119
+ colors.bold(colors.green(
120
+ "fedify lookup http://localhost:8000/users/john",
121
+ ))
122
+ }
123
+
124
+ `;
125
+
126
+ const getDevCommand = (pm: PackageManager) =>
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
+ );
136
+
137
+ async function isCommandAvailable(
138
+ { checkCommand, outputPattern }: {
139
+ checkCommand: [string, ...string[]];
140
+ outputPattern: RegExp;
141
+ },
142
+ ): Promise<boolean> {
143
+ try {
144
+ const { stdout } = await runSubCommand(checkCommand, {
145
+ stdio: [null, "pipe", null],
146
+ });
147
+ logger.debug(
148
+ "The stdout of the command {command} is: {stdout}",
149
+ { command: checkCommand, stdout },
150
+ );
151
+ return outputPattern.exec(stdout.trim()) ? true : false;
152
+ } catch (error) {
153
+ if (isNotFoundError(error)) return false;
154
+ logger.debug(
155
+ "The command {command} failed with the error: {error}",
156
+ { command: checkCommand, error },
157
+ );
158
+ throw error;
159
+ }
160
+ }
161
+
162
+ export async function createFile(path: string, content: string): Promise<void> {
163
+ await mkdir(dirname(path), { recursive: true });
164
+ await writeFile(path, content);
165
+ }
166
+
167
+ const isNotExistsError = (e: unknown) =>
168
+ isObject(e) && "code" in e && e.code === "ENOENT";
169
+
170
+ export const throwUnlessNotExists = throwIf(negate(isNotExistsError));
171
+
172
+ export const isDirectoryEmpty = async (
173
+ path: string,
174
+ ): Promise<boolean> => {
175
+ try {
176
+ const files = await readdir(path);
177
+ return files.length === 0;
178
+ } catch (e) {
179
+ throwUnlessNotExists(e);
180
+ return true;
181
+ }
182
+ };
183
+
184
+ export const getNextInitCommand = (
185
+ pm: PackageManager,
186
+ ): string[] => [
187
+ ...createNextAppCommand(pm),
188
+ ".",
189
+ "--ts",
190
+ "--app",
191
+ "--biome",
192
+ "--skip-install",
193
+ ];
194
+
195
+ const createNextAppCommand = (pm: PackageManager): string[] =>
196
+ pm === "deno"
197
+ ? ["deno", "run", "-A", "npm:create-next-app@latest"]
198
+ : pm === "bun"
199
+ ? ["bun", "create", "next-app"]
200
+ : pm === "npm"
201
+ ? ["npx", "create-next-app"]
202
+ : [pm, "dlx", "create-next-app"];
203
+
204
+ export const getNitroInitCommand = (
205
+ pm: PackageManager,
206
+ ): string[] => [
207
+ ...createNitroAppCommand(pm),
208
+ pm === "deno" ? "npm:giget@latest" : "giget@latest",
209
+ "nitro",
210
+ ".",
211
+ ];
212
+
213
+ const createNitroAppCommand = (pm: PackageManager): string[] =>
214
+ pm === "deno"
215
+ ? ["deno", "run", "-A"]
216
+ : pm === "bun"
217
+ ? ["bunx"]
218
+ : pm === "npm"
219
+ ? ["npx"]
220
+ : [pm, "dlx"];
@@ -0,0 +1,2 @@
1
+ export { default as runInit } from "./action/mod.ts";
2
+ export { initCommand } from "./command.ts";
@@ -0,0 +1,23 @@
1
+ import { createFederation, Person } from "@fedify/fedify";
2
+ import { getLogger } from "@logtape/logtape";
3
+ /* imports */
4
+
5
+ const logger = getLogger(/* logger */);
6
+
7
+ const federation = createFederation({
8
+ kv: /* kv */,
9
+ queue: /* queue */,
10
+ });
11
+
12
+ federation.setActorDispatcher(
13
+ "/users/{identifier}",
14
+ async (ctx, identifier) => {
15
+ return new Person({
16
+ id: ctx.getActorUri(identifier),
17
+ preferredUsername: identifier,
18
+ name: identifier,
19
+ });
20
+ },
21
+ );
22
+
23
+ export default federation;
@@ -0,0 +1,23 @@
1
+ import { configure, getConsoleSink } from "@logtape/logtape";
2
+ import { AsyncLocalStorage } from "node:async_hooks";
3
+
4
+ await configure({
5
+ contextLocalStorage: new AsyncLocalStorage(),
6
+ sinks: {
7
+ console: getConsoleSink(),
8
+ },
9
+ filters: {},
10
+ loggers: [
11
+ {
12
+ category: /* project name */,
13
+ lowestLevel: "debug",
14
+ sinks: ["console"],
15
+ },
16
+ { category: "fedify", lowestLevel: "info", sinks: ["console"] },
17
+ {
18
+ category: ["logtape", "meta"],
19
+ lowestLevel: "warning",
20
+ sinks: ["console"],
21
+ },
22
+ ],
23
+ });
@@ -0,0 +1,16 @@
1
+ import { integrateFederation } from "@fedify/express";
2
+ import { getLogger } from "@logtape/logtape";
3
+ import express from "express";
4
+ import federation from "./federation.ts";
5
+
6
+ const logger = getLogger("/* logger */");
7
+
8
+ export const app = express();
9
+
10
+ app.set("trust proxy", true);
11
+
12
+ app.use(integrateFederation(federation, () => undefined));
13
+
14
+ app.get("/", (_, res) => res.send("Hello, Fedify!"));
15
+
16
+ export default app;
@@ -0,0 +1,6 @@
1
+ import app from "./app.ts";
2
+ import "./logging.ts";
3
+
4
+ app.listen(8000, () => {
5
+ console.log("Server started at http://localhost:8000");
6
+ });
@@ -0,0 +1,14 @@
1
+ // @ts-nocheck this file is just a template
2
+ import { Hono } from "/* hono */";
3
+ import { federation } from "@fedify/hono";
4
+ import { getLogger } from "@logtape/logtape";
5
+ import fedi from "./federation.ts";
6
+
7
+ const logger = getLogger("/* logger */");
8
+
9
+ const app = new Hono();
10
+ app.use(federation(fedi, () => undefined));
11
+
12
+ app.get("/", (c) => c.text("Hello, Fedify!"));
13
+
14
+ export default app;
@@ -0,0 +1,10 @@
1
+ import { behindProxy } from "x-forwarded-fetch";
2
+ import app from "./app.tsx";
3
+ import "./logging.ts";
4
+
5
+ const server = Bun.serve({
6
+ port: 8000,
7
+ fetch: behindProxy(app.fetch.bind(app)),
8
+ });
9
+
10
+ console.log("Server started at", server.url.href);
@@ -0,0 +1,13 @@
1
+ import { behindProxy } from "@hongminhee/x-forwarded-fetch";
2
+ import "@std/dotenv/load";
3
+ import app from "./app.tsx";
4
+ import "./logging.ts";
5
+
6
+ Deno.serve(
7
+ {
8
+ port: 8000,
9
+ onListen: ({ port, hostname }) =>
10
+ console.log("Server started at http://" + hostname + ":" + port),
11
+ },
12
+ behindProxy(app.fetch.bind(app)),
13
+ );
@@ -0,0 +1,14 @@
1
+ // @ts-nocheck this file is just a template
2
+ import { serve } from "@hono/node-server";
3
+ import { behindProxy } from "x-forwarded-fetch";
4
+ import app from "./app.tsx";
5
+ import "./logging.ts";
6
+
7
+ serve(
8
+ {
9
+ port: 8000,
10
+ fetch: behindProxy(app.fetch.bind(app)),
11
+ },
12
+ (info) =>
13
+ console.log("Server started at http://" + info.address + ":" + info.port),
14
+ );
@@ -0,0 +1,45 @@
1
+ import { fedifyWith } from "@fedify/next";
2
+ import federation from "./federation";
3
+
4
+ export default fedifyWith(federation)(
5
+ /*
6
+ function (request: Request) {
7
+ // If you need to handle other requests besides federation
8
+ // requests in middleware, you can do it here.
9
+ // If you handle only federation requests in middleware,
10
+ // you don't need this function.
11
+ return NextResponse.next();
12
+ },
13
+ */
14
+ )
15
+
16
+ // This config needs because middleware process only requests with the
17
+ // "Accept" header matching the federation accept regex.
18
+ // More details: https://nextjs.org/docs/app/api-reference/file-conventions/middleware#config-object-optional
19
+ export const config = {
20
+ runtime: "nodejs",
21
+ matcher: [
22
+ {
23
+ source: "/:path*",
24
+ has: [
25
+ {
26
+ type: "header",
27
+ key: "Accept",
28
+ value: ".*application\\/((jrd|activity|ld)\\+json|xrd\\+xml).*",
29
+ },
30
+ ],
31
+ },
32
+ {
33
+ source: "/:path*",
34
+ has: [
35
+ {
36
+ type: "header",
37
+ key: "content-type",
38
+ value: ".*application\\/((jrd|activity|ld)\\+json|xrd\\+xml).*",
39
+ },
40
+ ],
41
+ },
42
+ { source: "/.well-known/nodeinfo" },
43
+ { source: "/.well-known/x-nodeinfo2" },
44
+ ],
45
+ };
@@ -0,0 +1,5 @@
1
+ // https://nitro.unjs.io/config
2
+ export default defineNitroConfig({
3
+ srcDir: "server",
4
+ errorHandler: "~/error"
5
+ });
@@ -0,0 +1,3 @@
1
+ import { onError } from "@fedify/h3";
2
+
3
+ export default onError;
@@ -0,0 +1,8 @@
1
+
2
+ import { integrateFederation } from "@fedify/h3";
3
+ import federation from "../federation"
4
+
5
+ export default integrateFederation(
6
+ federation,
7
+ (event, request) => undefined,
8
+ );
@@ -0,0 +1,88 @@
1
+ import type { RequiredNotNull } from "../utils.ts";
2
+ import type { InitCommand } from "./command.ts";
3
+ import type {
4
+ KV_STORE,
5
+ MESSAGE_QUEUE,
6
+ PACKAGE_MANAGER,
7
+ WEB_FRAMEWORK,
8
+ } from "./const.ts";
9
+
10
+ export type PackageManager = typeof PACKAGE_MANAGER[number];
11
+ export type WebFramework = typeof WEB_FRAMEWORK[number];
12
+ export type MessageQueue = typeof MESSAGE_QUEUE[number];
13
+ export type KvStore = typeof KV_STORE[number];
14
+
15
+ export type MessageQueues = Record<MessageQueue, MessageQueueDescription>;
16
+ export type KvStores = Record<KvStore, KvStoreDescription>;
17
+ export type WebFrameworks = Record<WebFramework, WebFrameworkDescription>;
18
+ export type PackageManagers = Record<PackageManager, PackageManagerDescription>;
19
+ export type Runtimes = Record<PackageManager, RuntimeDescription>;
20
+
21
+ export interface RuntimeDescription {
22
+ label: string;
23
+ checkCommand: [string, ...string[]];
24
+ outputPattern: RegExp;
25
+ }
26
+
27
+ export interface PackageManagerDescription {
28
+ label: string;
29
+ checkCommand: [string, ...string[]];
30
+ outputPattern: RegExp;
31
+ installUrl: string;
32
+ }
33
+
34
+ export interface WebFrameworkInitializer {
35
+ command?: string[];
36
+ dependencies?: object;
37
+ devDependencies?: object;
38
+ federationFile: string;
39
+ loggingFile: string;
40
+ files?: Record<string, string>;
41
+ compilerOptions?: Record<string, string | boolean | number | string[] | null>;
42
+ tasks?: Record<string, string>;
43
+ instruction: string;
44
+ }
45
+
46
+ export interface WebFrameworkDescription {
47
+ label: string;
48
+ packageManagers: readonly PackageManager[];
49
+ init(
50
+ projectName: string,
51
+ pm: PackageManager,
52
+ ): WebFrameworkInitializer;
53
+ }
54
+
55
+ export interface MessageQueueDescription {
56
+ label: string;
57
+ packageManagers: readonly PackageManager[];
58
+ dependencies?: Record<string, string>;
59
+ devDependencies?: Record<string, string>;
60
+ imports: Record<string, Record<string, string>>;
61
+ object: string;
62
+ denoUnstable?: string[];
63
+ env?: Record<string, string>;
64
+ }
65
+
66
+ export interface KvStoreDescription {
67
+ label: string;
68
+ packageManagers: readonly PackageManager[];
69
+ dependencies?: Record<string, string>;
70
+ devDependencies?: Record<string, string>;
71
+ imports: Record<string, Record<string, string>>;
72
+ object: string;
73
+ denoUnstable?: string[];
74
+ env?: Record<string, string>;
75
+ }
76
+
77
+ export type InitCommandOptions = RequiredNotNull<InitCommand>;
78
+
79
+ export interface InitCommandData extends InitCommandOptions {
80
+ readonly projectName: string;
81
+ readonly initializer: WebFrameworkInitializer;
82
+ readonly kv: KvStoreDescription;
83
+ readonly mq: MessageQueueDescription;
84
+ readonly env: Record<string, string>;
85
+ }
86
+
87
+ export type InitCommandIo = (data: InitCommandData) => void;
88
+ export type InitCommandAsyncIo = (data: InitCommandData) => Promise<void>;