@fedify/cli 2.0.0-pr.479.1922 → 2.0.1

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 (160) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -3
  3. package/dist/cache.js +17 -3
  4. package/dist/config.js +105 -0
  5. package/dist/deno.js +18 -8
  6. package/dist/generate-vocab/action.js +1 -1
  7. package/dist/imagerenderer.js +1 -1
  8. package/dist/inbox/rendercode.js +11 -21
  9. package/dist/inbox.js +162 -132
  10. package/dist/init/mod.js +3 -3
  11. package/dist/log.js +35 -1
  12. package/dist/lookup.js +55 -23
  13. package/dist/mod.js +95 -18
  14. package/dist/nodeinfo.js +39 -22
  15. package/dist/options.js +84 -0
  16. package/dist/relay.js +136 -0
  17. package/dist/tempserver.js +15 -8
  18. package/dist/tunnel.js +6 -10
  19. package/dist/utils.js +19 -108
  20. package/dist/webfinger/action.js +1 -1
  21. package/dist/webfinger/command.js +17 -9
  22. package/dist/webfinger/lib.js +3 -3
  23. package/package.json +50 -28
  24. package/deno.json +0 -71
  25. package/dist/globals.js +0 -49
  26. package/dist/init/action/configs.js +0 -91
  27. package/dist/init/action/const.js +0 -10
  28. package/dist/init/action/deps.js +0 -50
  29. package/dist/init/action/dir.js +0 -16
  30. package/dist/init/action/env.js +0 -13
  31. package/dist/init/action/install.js +0 -20
  32. package/dist/init/action/mod.js +0 -39
  33. package/dist/init/action/notice.js +0 -55
  34. package/dist/init/action/patch.js +0 -147
  35. package/dist/init/action/precommand.js +0 -28
  36. package/dist/init/action/recommend.js +0 -24
  37. package/dist/init/action/set.js +0 -31
  38. package/dist/init/action/templates.js +0 -58
  39. package/dist/init/action/utils.js +0 -50
  40. package/dist/init/ask/dir.js +0 -82
  41. package/dist/init/ask/kv.js +0 -44
  42. package/dist/init/ask/mod.js +0 -16
  43. package/dist/init/ask/mq.js +0 -46
  44. package/dist/init/ask/pm.js +0 -49
  45. package/dist/init/ask/wf.js +0 -29
  46. package/dist/init/command.js +0 -50
  47. package/dist/init/const.js +0 -31
  48. package/dist/init/json/biome.js +0 -24
  49. package/dist/init/json/kv.js +0 -53
  50. package/dist/init/json/mq.js +0 -72
  51. package/dist/init/json/pm.js +0 -44
  52. package/dist/init/json/rt.js +0 -39
  53. package/dist/init/json/vscode-settings-for-deno.js +0 -53
  54. package/dist/init/json/vscode-settings.js +0 -49
  55. package/dist/init/lib.js +0 -136
  56. package/dist/init/templates/defaults/federation.ts.tpl +0 -23
  57. package/dist/init/templates/defaults/logging.ts.tpl +0 -23
  58. package/dist/init/templates/express/app.ts.tpl +0 -16
  59. package/dist/init/templates/express/index.ts.tpl +0 -6
  60. package/dist/init/templates/hono/app.tsx.tpl +0 -14
  61. package/dist/init/templates/hono/index/bun.ts.tpl +0 -10
  62. package/dist/init/templates/hono/index/deno.ts.tpl +0 -13
  63. package/dist/init/templates/hono/index/node.ts.tpl +0 -14
  64. package/dist/init/templates/next/middleware.ts.tpl +0 -45
  65. package/dist/init/templates/nitro/.env.test.tpl +0 -1
  66. package/dist/init/templates/nitro/nitro.config.ts.tpl +0 -14
  67. package/dist/init/templates/nitro/server/error.ts.tpl +0 -3
  68. package/dist/init/templates/nitro/server/middleware/federation.ts.tpl +0 -8
  69. package/dist/init/test/action.js +0 -17
  70. package/dist/init/test/create.js +0 -100
  71. package/dist/init/test/fill.js +0 -32
  72. package/dist/init/test/lookup.js +0 -190
  73. package/dist/init/test/run.js +0 -25
  74. package/dist/init/test/utils.js +0 -17
  75. package/dist/init/webframeworks.js +0 -136
  76. package/scripts/pack.ts +0 -71
  77. package/src/cache.ts +0 -17
  78. package/src/docloader.ts +0 -67
  79. package/src/generate-vocab/action.ts +0 -17
  80. package/src/generate-vocab/command.ts +0 -44
  81. package/src/generate-vocab/mod.ts +0 -2
  82. package/src/globals.ts +0 -43
  83. package/src/imagerenderer.ts +0 -149
  84. package/src/inbox/entry.ts +0 -10
  85. package/src/inbox/rendercode.ts +0 -68
  86. package/src/inbox/view.tsx +0 -598
  87. package/src/inbox.tsx +0 -536
  88. package/src/init/action/configs.ts +0 -133
  89. package/src/init/action/const.ts +0 -9
  90. package/src/init/action/deps.ts +0 -161
  91. package/src/init/action/dir.ts +0 -11
  92. package/src/init/action/env.ts +0 -14
  93. package/src/init/action/install.ts +0 -24
  94. package/src/init/action/mod.ts +0 -66
  95. package/src/init/action/notice.ts +0 -103
  96. package/src/init/action/patch.ts +0 -233
  97. package/src/init/action/precommand.ts +0 -29
  98. package/src/init/action/recommend.ts +0 -38
  99. package/src/init/action/set.ts +0 -65
  100. package/src/init/action/templates.ts +0 -96
  101. package/src/init/action/utils.ts +0 -64
  102. package/src/init/ask/dir.ts +0 -98
  103. package/src/init/ask/kv.ts +0 -82
  104. package/src/init/ask/mod.ts +0 -23
  105. package/src/init/ask/mq.ts +0 -86
  106. package/src/init/ask/pm.ts +0 -58
  107. package/src/init/ask/wf.ts +0 -27
  108. package/src/init/command.ts +0 -135
  109. package/src/init/const.ts +0 -4
  110. package/src/init/json/biome.json +0 -17
  111. package/src/init/json/kv.json +0 -39
  112. package/src/init/json/mq.json +0 -95
  113. package/src/init/json/pm.json +0 -47
  114. package/src/init/json/rt.json +0 -42
  115. package/src/init/json/vscode-settings-for-deno.json +0 -43
  116. package/src/init/json/vscode-settings.json +0 -41
  117. package/src/init/lib.ts +0 -223
  118. package/src/init/mod.ts +0 -3
  119. package/src/init/templates/defaults/federation.ts.tpl +0 -23
  120. package/src/init/templates/defaults/logging.ts.tpl +0 -23
  121. package/src/init/templates/express/app.ts.tpl +0 -16
  122. package/src/init/templates/express/index.ts.tpl +0 -6
  123. package/src/init/templates/hono/app.tsx.tpl +0 -14
  124. package/src/init/templates/hono/index/bun.ts.tpl +0 -10
  125. package/src/init/templates/hono/index/deno.ts.tpl +0 -13
  126. package/src/init/templates/hono/index/node.ts.tpl +0 -14
  127. package/src/init/templates/next/middleware.ts.tpl +0 -45
  128. package/src/init/templates/nitro/.env.test.tpl +0 -1
  129. package/src/init/templates/nitro/nitro.config.ts.tpl +0 -14
  130. package/src/init/templates/nitro/server/error.ts.tpl +0 -3
  131. package/src/init/templates/nitro/server/middleware/federation.ts.tpl +0 -8
  132. package/src/init/test/action.ts +0 -28
  133. package/src/init/test/create.ts +0 -137
  134. package/src/init/test/fill.ts +0 -67
  135. package/src/init/test/lookup.ts +0 -254
  136. package/src/init/test/run.ts +0 -39
  137. package/src/init/test/types.ts +0 -27
  138. package/src/init/test/utils.ts +0 -21
  139. package/src/init/types.ts +0 -89
  140. package/src/init/webframeworks.ts +0 -168
  141. package/src/kv.bun.ts +0 -12
  142. package/src/kv.node.ts +0 -11
  143. package/src/log.ts +0 -64
  144. package/src/lookup.test.ts +0 -182
  145. package/src/lookup.ts +0 -563
  146. package/src/mod.ts +0 -62
  147. package/src/nodeinfo.test.ts +0 -229
  148. package/src/nodeinfo.ts +0 -454
  149. package/src/table.ts +0 -17
  150. package/src/tempserver.ts +0 -87
  151. package/src/tunnel.test.ts +0 -157
  152. package/src/tunnel.ts +0 -94
  153. package/src/utils.ts +0 -254
  154. package/src/webfinger/action.ts +0 -50
  155. package/src/webfinger/command.ts +0 -64
  156. package/src/webfinger/error.ts +0 -47
  157. package/src/webfinger/lib.ts +0 -37
  158. package/src/webfinger/mod.test.ts +0 -79
  159. package/src/webfinger/mod.ts +0 -2
  160. package/tsdown.config.ts +0 -35
package/dist/init/lib.js DELETED
@@ -1,136 +0,0 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
4
- import deno_default from "../deno.js";
5
- import { isNotFoundError, runSubCommand } from "../utils.js";
6
- import kv_default from "./json/kv.js";
7
- import mq_default from "./json/mq.js";
8
- import pm_default from "./json/pm.js";
9
- import rt_default from "./json/rt.js";
10
- import webframeworks_default from "./webframeworks.js";
11
- import { dirname, join } from "node:path";
12
- import { mkdir, readdir, writeFile } from "node:fs/promises";
13
- import { commandLine, message } from "@optique/core/message";
14
- import process from "node:process";
15
- import { getLogger } from "@logtape/logtape";
16
- import { entries, evolve, fromEntries, isObject, map, negate, pipe, throwIf, when } from "@fxts/core";
17
- import { toMerged } from "es-toolkit";
18
- import { readFileSync } from "node:fs";
19
-
20
- //#region src/init/lib.ts
21
- const PACKAGE_VERSION = deno_default.version;
22
- const logger = getLogger([
23
- "fedify",
24
- "cli",
25
- "init"
26
- ]);
27
- const addFedifyDeps = (json) => Object.fromEntries(Object.entries(json).map(([key, value]) => [key, toMerged(value, { dependencies: { [`@fedify/${key}`]: PACKAGE_VERSION } })]));
28
- const kvStores = addFedifyDeps(kv_default);
29
- const messageQueues = addFedifyDeps(mq_default);
30
- const toRegExp = (str) => new RegExp(str);
31
- const convertPattern = (obj) => pipe(obj, entries, map(([key, value]) => [key, evolve({ outputPattern: toRegExp })(value)]), fromEntries);
32
- const packageManagers = convertPattern(pm_default);
33
- const runtimes = convertPattern(rt_default);
34
- const getLabel = (name) => pipe(name, whenHasLabel(webframeworks_default), whenHasLabel(packageManagers), whenHasLabel(messageQueues), whenHasLabel(kvStores), whenHasLabel(runtimes));
35
- const whenHasLabel = (desc) => when((name) => name in desc, (name) => desc[name].label);
36
- const getInstallUrl = (pm) => packageManagers[pm].installUrl;
37
- async function isPackageManagerAvailable(pm) {
38
- if (await isCommandAvailable(packageManagers[pm])) return true;
39
- if (process.platform !== "win32") return false;
40
- const cmd = [packageManagers[pm].checkCommand[0] + ".cmd", ...packageManagers[pm].checkCommand.slice(1)];
41
- if (await isCommandAvailable({
42
- ...packageManagers[pm],
43
- checkCommand: cmd
44
- })) return true;
45
- return false;
46
- }
47
- const readTemplate = (templatePath) => readFileSync(join(import.meta.dirname, "templates", ...(templatePath + ".tpl").split("/")), "utf8");
48
- const getInstruction = (pm, port) => message`
49
- To start the server, run the following command:
50
-
51
- ${commandLine(getDevCommand(pm))}
52
-
53
- Then, try look up an actor from your server:
54
-
55
- ${commandLine(`fedify lookup http://localhost:${port}/users/john`)}
56
-
57
- `;
58
- const getDevCommand = (pm) => pm === "deno" ? "deno task dev" : pm === "bun" ? "bun dev" : `${pm} run dev`;
59
- async function isCommandAvailable({ checkCommand, outputPattern }) {
60
- try {
61
- const { stdout } = await runSubCommand(checkCommand, { stdio: [
62
- null,
63
- "pipe",
64
- null
65
- ] });
66
- logger.debug("The stdout of the command {command} is: {stdout}", {
67
- command: checkCommand,
68
- stdout
69
- });
70
- return outputPattern.exec(stdout.trim()) ? true : false;
71
- } catch (error) {
72
- if (isNotFoundError(error)) return false;
73
- logger.debug("The command {command} failed with the error: {error}", {
74
- command: checkCommand,
75
- error
76
- });
77
- throw error;
78
- }
79
- }
80
- async function createFile(path$1, content) {
81
- await mkdir(dirname(path$1), { recursive: true });
82
- await writeFile(path$1, content);
83
- }
84
- const isNotExistsError = (e) => isObject(e) && "code" in e && e.code === "ENOENT";
85
- const throwUnlessNotExists = throwIf(negate(isNotExistsError));
86
- const isDirectoryEmpty = async (path$1) => {
87
- try {
88
- const files = await readdir(path$1);
89
- return files.length === 0;
90
- } catch (e) {
91
- throwUnlessNotExists(e);
92
- return true;
93
- }
94
- };
95
- /**
96
- * Converts a package manager to its corresponding runtime.
97
- * @param pm - The package manager (deno, bun, npm, yarn, pnpm)
98
- * @returns The runtime name (deno, bun, or node)
99
- */
100
- const packageManagerToRuntime = (pm) => pm === "deno" ? "deno" : pm === "bun" ? "bun" : "node";
101
- const getNextInitCommand = (pm) => [
102
- ...createNextAppCommand(pm),
103
- ".",
104
- "--yes"
105
- ];
106
- const createNextAppCommand = (pm) => pm === "deno" ? [
107
- "deno",
108
- "-Ar",
109
- "npm:create-next-app@latest"
110
- ] : pm === "bun" ? [
111
- "bun",
112
- "create",
113
- "next-app"
114
- ] : pm === "npm" ? ["npx", "create-next-app"] : [
115
- pm,
116
- "dlx",
117
- "create-next-app"
118
- ];
119
- const getNitroInitCommand = (pm) => [
120
- ...createNitroAppCommand(pm),
121
- pm === "deno" ? "npm:giget@latest" : "giget@latest",
122
- "nitro",
123
- ".",
124
- "&&",
125
- "rm",
126
- "nitro.config.ts"
127
- ];
128
- const createNitroAppCommand = (pm) => pm === "deno" ? [
129
- "deno",
130
- "run",
131
- "-A"
132
- ] : pm === "bun" ? ["bunx"] : pm === "npm" ? ["npx"] : [pm, "dlx"];
133
- const isTest = ({ testMode }) => testMode;
134
-
135
- //#endregion
136
- export { PACKAGE_VERSION, createFile, getDevCommand, getInstallUrl, getInstruction, getLabel, getNextInitCommand, getNitroInitCommand, isDirectoryEmpty, isPackageManagerAvailable, isTest, kvStores, logger, messageQueues, packageManagerToRuntime, readTemplate, throwUnlessNotExists };
@@ -1,23 +0,0 @@
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;
@@ -1,23 +0,0 @@
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
- });
@@ -1,16 +0,0 @@
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;
@@ -1,6 +0,0 @@
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
- });
@@ -1,14 +0,0 @@
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;
@@ -1,10 +0,0 @@
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);
@@ -1,13 +0,0 @@
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
- );
@@ -1,14 +0,0 @@
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
- );
@@ -1,45 +0,0 @@
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
- };
@@ -1 +0,0 @@
1
- HOST=127.0.0.1
@@ -1,14 +0,0 @@
1
- import { defineNitroConfig } from "nitropack/config"
2
-
3
- // https://nitro.build/config
4
- export default defineNitroConfig({
5
- errorHandler: "~/error",
6
- esbuild: {
7
- options: {
8
- target: "esnext",
9
- },
10
- },
11
- compatibilityDate: "latest",
12
- srcDir: "server",
13
- imports: false
14
- });
@@ -1,3 +0,0 @@
1
- import { onError } from "@fedify/h3";
2
-
3
- export default onError;
@@ -1,8 +0,0 @@
1
-
2
- import { integrateFederation } from "@fedify/h3";
3
- import federation from "../federation"
4
-
5
- export default integrateFederation(
6
- federation,
7
- (event, request) => undefined,
8
- );
@@ -1,17 +0,0 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
4
- import { set } from "../../utils.js";
5
- import { fillEmptyOptions } from "./fill.js";
6
- import run_default from "./run.js";
7
- import { emptyTestDir, genRunId, genTestDirPrefix, logTestDir } from "./utils.js";
8
- import { pipe, tap, when } from "@fxts/core";
9
-
10
- //#region src/init/test/action.ts
11
- const runTestInit = (options) => pipe(options, set("runId", genRunId), set("testDirPrefix", genTestDirPrefix), tap(emptyTestDir), fillEmptyOptions, tap(logTestDir), tap(when(isDryRun, run_default(true))), tap(when(isHydRun, run_default(false))));
12
- const isDryRun = ({ dryRun }) => dryRun;
13
- const isHydRun = ({ hydRun }) => hydRun;
14
- var action_default = runTestInit;
15
-
16
- //#endregion
17
- export { action_default as default };
@@ -1,100 +0,0 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
4
- import { CommandError, printErrorMessage, printMessage, product, runSubCommand } from "../../utils.js";
5
- import pm_default from "../json/pm.js";
6
- import webframeworks_default from "../webframeworks.js";
7
- import { kvStores, messageQueues } from "../lib.js";
8
- import { join, sep } from "node:path";
9
- import { appendFile, mkdir } from "node:fs/promises";
10
- import { values } from "@optique/core";
11
- import process from "node:process";
12
- import { filter, isEmpty, pipe, toArray } from "@fxts/core";
13
-
14
- //#region src/init/test/create.ts
15
- const BANNED_PMS = ["bun", "yarn"];
16
- const createTestApp = (testDirPrefix, dry) => async (options) => {
17
- const testDir = join(testDirPrefix, ...options);
18
- const vals = values(testDir.split(sep).slice(-4));
19
- try {
20
- const result = await runSubCommand(toArray(genInitCommand(testDir, dry, options)), {
21
- cwd: join(import.meta.dirname, "../../.."),
22
- stdio: [
23
- "ignore",
24
- "pipe",
25
- "pipe"
26
- ]
27
- });
28
- await saveOutputs(testDir, result);
29
- printMessage` Pass: ${vals}`;
30
- return testDir;
31
- } catch (error) {
32
- if (error instanceof CommandError) await saveOutputs(testDir, {
33
- stdout: error.stdout,
34
- stderr: error.stderr
35
- });
36
- else {
37
- const errorMessage = error instanceof Error ? error.message : String(error);
38
- await saveOutputs(testDir, {
39
- stdout: "",
40
- stderr: errorMessage
41
- });
42
- }
43
- printMessage` Fail: ${vals}`;
44
- return "";
45
- }
46
- };
47
- var create_default = createTestApp;
48
- function* genInitCommand(testDir, dry, [webFramework, packageManager, kvStore, messageQueue]) {
49
- yield "deno";
50
- yield "run";
51
- yield "-A";
52
- yield "src/mod.ts";
53
- yield "init";
54
- yield testDir;
55
- yield "-w";
56
- yield webFramework;
57
- yield "-p";
58
- yield packageManager;
59
- yield "-k";
60
- yield kvStore;
61
- yield "-m";
62
- yield messageQueue;
63
- yield "--test-mode";
64
- if (dry) yield "-d";
65
- }
66
- const generateTestCases = ({ webFramework, packageManager, kvStore, messageQueue }) => {
67
- const pms = filterPackageManager(packageManager);
68
- exitIfCasesEmpty([
69
- webFramework,
70
- pms,
71
- kvStore,
72
- messageQueue
73
- ]);
74
- return product(webFramework, pms, kvStore, messageQueue);
75
- };
76
- const filterPackageManager = (pm) => pipe(pm, filter((pm$1) => BANNED_PMS.includes(pm$1) ? printErrorMessage`${pm_default[pm$1]["label"]} is not \
77
- supported in test mode yet because ${pm_default[pm$1]["label"]} don't \
78
- support local file dependencies properly.` : true), toArray);
79
- const exitIfCasesEmpty = (cases) => {
80
- if (cases.some(isEmpty)) {
81
- printErrorMessage`No test cases to run. Exiting.`;
82
- process.exit(1);
83
- }
84
- };
85
- const saveOutputs = async (dirPath, { stdout, stderr }) => {
86
- await mkdir(dirPath, { recursive: true });
87
- if (stdout) await appendFile(join(dirPath, "out.txt"), stdout + "\n", "utf8");
88
- if (stderr) await appendFile(join(dirPath, "err.txt"), stderr + "\n", "utf8");
89
- };
90
- function filterOptions(options) {
91
- const [wf, pm, kv, mq] = options;
92
- return [
93
- webframeworks_default[wf].packageManagers,
94
- kvStores[kv].packageManagers,
95
- messageQueues[mq].packageManagers
96
- ].every((pms) => pms.includes(pm));
97
- }
98
-
99
- //#endregion
100
- export { create_default as default, filterOptions, generateTestCases };
@@ -1,32 +0,0 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
4
- import { KV_STORE, MESSAGE_QUEUE, PACKAGE_MANAGER, WEB_FRAMEWORK } from "../const.js";
5
- import { isEmpty, omit, pipe } from "@fxts/core";
6
-
7
- //#region src/init/test/fill.ts
8
- const fillEmptyOptions = (options) => pipe(options, fillWebFramework, fillPackageManager, fillKVStore, fillMessageQueue, fillRunMode);
9
- const fillOption = (key, allValues) => (options) => ({
10
- ...options,
11
- [key]: isEmpty(options[key]) ? allValues : options[key].filter((i) => allValues.includes(i))
12
- });
13
- const fillWebFramework = fillOption("webFramework", WEB_FRAMEWORK);
14
- const fillPackageManager = fillOption("packageManager", PACKAGE_MANAGER);
15
- const fillKVStore = fillOption("kvStore", KV_STORE);
16
- const fillMessageQueue = fillOption("messageQueue", MESSAGE_QUEUE);
17
- const fillRunMode = (options) => pipe(options, (options$1) => "noHydRun" in options$1 ? {
18
- ...omit(["noHydRun"], options$1),
19
- hydRun: !options$1.noHydRun
20
- } : {
21
- ...options$1,
22
- hydRun: true
23
- }, (options$1) => "noDryRun" in options$1 ? {
24
- ...omit(["noDryRun"], options$1),
25
- dryRun: !options$1.noDryRun
26
- } : {
27
- ...options$1,
28
- dryRun: true
29
- });
30
-
31
- //#endregion
32
- export { fillEmptyOptions };
@@ -1,190 +0,0 @@
1
-
2
- import { Temporal } from "@js-temporal/polyfill";
3
-
4
- import { printErrorMessage, printMessage, runSubCommand } from "../../utils.js";
5
- import webframeworks_default from "../webframeworks.js";
6
- import { getDevCommand } from "../lib.js";
7
- import { join, sep } from "node:path";
8
- import { values } from "@optique/core";
9
- import process from "node:process";
10
- import { spawn } from "node:child_process";
11
- import { createWriteStream } from "node:fs";
12
- import { isEmpty } from "@fxts/core/index.js";
13
-
14
- //#region src/init/test/lookup.ts
15
- const HANDLE = "john";
16
- const STARTUP_TIMEOUT = 3e4;
17
- const CWD = process.cwd();
18
- const BANNED_WFS = ["next"];
19
- /**
20
- * Run servers for all generated apps and test them with the lookup command.
21
- *
22
- * @param dirs - Array of paths to generated app directories
23
- */
24
- async function runServerAndLookupUser(dirs) {
25
- const valid = dirs.filter(Boolean);
26
- if (valid.length === 0) {
27
- printErrorMessage`\nNo directories to lookup test.`;
28
- return;
29
- }
30
- const filtered = filterWebFrameworks(valid);
31
- printMessage`\nLookup Test start for ${String(filtered.length)} app(s)!`;
32
- const results = await Array.fromAsync(filtered, testApp);
33
- const successCount = results.filter(Boolean).length;
34
- const failCount = results.length - successCount;
35
- printMessage`Lookup Test Results:
36
- Total: ${String(results.length)}
37
- Passed: ${String(successCount)}
38
- Failed: ${String(failCount)}\n\n`;
39
- }
40
- function filterWebFrameworks(dirs) {
41
- const wfs = new Set(dirs.map((dir) => dir.split(sep).slice(-4, -3)[0]));
42
- const hasBanned = BANNED_WFS.filter((wf) => wfs.has(wf));
43
- if (isEmpty(hasBanned)) return dirs;
44
- const bannedLabels = hasBanned.map((wf) => webframeworks_default[wf]["label"]);
45
- printErrorMessage`\n${values(bannedLabels)} is not supported in lookup test yet.`;
46
- return dirs.filter((dir) => !BANNED_WFS.includes(dir.split(sep).slice(-4, -3)[0]));
47
- }
48
- /**
49
- * Run the dev server and test with lookup command.
50
- */
51
- async function testApp(dir) {
52
- const [wf, pm, kv, mq] = dir.split(sep).slice(-4);
53
- printMessage` Testing ${values([
54
- wf,
55
- pm,
56
- kv,
57
- mq
58
- ])}...`;
59
- const result = await serverClosure(dir, getDevCommand(pm), sendLookup);
60
- printMessage` Lookup ${result ? "successful" : "failed"} for ${values([
61
- wf,
62
- pm,
63
- kv,
64
- mq
65
- ])}!`;
66
- if (!result) printMessage` Check out these files for more details:
67
- ${join(dir, "out.txt")} and
68
- ${join(dir, "err.txt")}\n`;
69
- printMessage`\n`;
70
- return result;
71
- }
72
- const sendLookup = async (port) => {
73
- const serverUrl = `http://localhost:${port}`;
74
- const lookupTarget = `${serverUrl}/users/${HANDLE}`;
75
- printMessage` Waiting for server to start at ${serverUrl}...`;
76
- const isReady = await waitForServer(serverUrl, STARTUP_TIMEOUT);
77
- if (!isReady) {
78
- printErrorMessage`Server did not start within \
79
- ${String(STARTUP_TIMEOUT)}ms`;
80
- return false;
81
- }
82
- printMessage` Server is ready. Running lookup command...`;
83
- try {
84
- await runSubCommand([
85
- "deno",
86
- "task",
87
- "cli",
88
- "lookup",
89
- lookupTarget
90
- ], { cwd: CWD });
91
- return true;
92
- } catch (error) {
93
- if (error instanceof Error) printErrorMessage`${error.message}`;
94
- }
95
- return false;
96
- };
97
- /**
98
- * Wait for the server to be ready by checking if it responds to requests.
99
- */
100
- async function waitForServer(url, timeout) {
101
- const startTime = Date.now();
102
- while (Date.now() - startTime < timeout) {
103
- try {
104
- const response = await fetch(url, { signal: AbortSignal.timeout(1e3) });
105
- if (response.ok) return true;
106
- } catch {}
107
- await new Promise((resolve) => setTimeout(resolve, 500));
108
- }
109
- return false;
110
- }
111
- async function serverClosure(dir, cmd, callback) {
112
- const devCommand = cmd.split(" ");
113
- const serverProcess = spawn(devCommand[0], devCommand.slice(1), {
114
- cwd: dir,
115
- stdio: [
116
- "ignore",
117
- "pipe",
118
- "pipe"
119
- ],
120
- detached: true
121
- });
122
- const stdout = createWriteStream(join(dir, "out.txt"), { flags: "a" });
123
- const stderr = createWriteStream(join(dir, "err.txt"), { flags: "a" });
124
- serverProcess.stdout?.pipe(stdout);
125
- serverProcess.stderr?.pipe(stderr);
126
- try {
127
- const port = await determinePort(serverProcess);
128
- return await callback(port);
129
- } finally {
130
- try {
131
- process.kill(-serverProcess.pid, "SIGKILL");
132
- } catch {
133
- serverProcess.kill("SIGKILL");
134
- stdout.end();
135
- stderr.end();
136
- }
137
- }
138
- }
139
- function determinePort(server) {
140
- return new Promise((resolve, reject) => {
141
- const timeout = setTimeout(() => {
142
- reject(/* @__PURE__ */ new Error("Timeout: Could not determine port from server output"));
143
- }, STARTUP_TIMEOUT);
144
- let stdoutData = "";
145
- let stderrData = "";
146
- const portPatterns = [
147
- /listening on.*:(\d+)/i,
148
- /server.*:(\d+)/i,
149
- /port\s*:?\s*(\d+)/i,
150
- /https?:\/\/localhost:(\d+)/i,
151
- /https?:\/\/0\.0\.0\.0:(\d+)/i,
152
- /https?:\/\/127\.0\.0\.1:(\d+)/i,
153
- /https?:\/\/[^:]+:(\d+)/i
154
- ];
155
- const checkForPort = (data) => {
156
- for (const pattern of portPatterns) {
157
- const match = data.match(pattern);
158
- if (match && match[1]) {
159
- const port = Number.parseInt(match[1], 10);
160
- if (port > 0 && port < 65536) {
161
- clearTimeout(timeout);
162
- return port;
163
- }
164
- }
165
- }
166
- return null;
167
- };
168
- server.stdout.on("data", (chunk) => {
169
- stdoutData += chunk.toString();
170
- const port = checkForPort(stdoutData);
171
- if (port) resolve(port);
172
- });
173
- server.stderr.on("data", (chunk) => {
174
- stderrData += chunk.toString();
175
- const port = checkForPort(stderrData);
176
- if (port) resolve(port);
177
- });
178
- server.on("error", (err) => {
179
- clearTimeout(timeout);
180
- reject(err);
181
- });
182
- server.on("exit", (code) => {
183
- clearTimeout(timeout);
184
- reject(/* @__PURE__ */ new Error(`Server exited with code ${code} before port could be determined`));
185
- });
186
- });
187
- }
188
-
189
- //#endregion
190
- export { runServerAndLookupUser };