@fedify/cli 2.0.0-pr.474.1879 → 2.0.0-pr.479.1900
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 +1 -1
- package/dist/deno.js +1 -1
- package/dist/imagerenderer.js +1 -1
- package/dist/inbox.js +2 -5
- package/dist/init/action/configs.js +22 -13
- package/dist/init/action/const.js +10 -0
- package/dist/init/action/deps.js +26 -28
- package/dist/init/action/install.js +11 -13
- package/dist/init/action/mod.js +1 -1
- package/dist/init/action/notice.js +12 -19
- package/dist/init/action/patch.js +33 -27
- package/dist/init/action/precommand.js +7 -2
- package/dist/init/action/recommend.js +1 -1
- package/dist/init/action/set.js +1 -1
- package/dist/init/action/templates.js +2 -1
- package/dist/init/ask/kv.js +24 -13
- package/dist/init/ask/mq.js +26 -13
- package/dist/init/command.js +20 -3
- package/dist/init/lib.js +20 -13
- package/dist/init/mod.js +2 -1
- package/dist/init/templates/nitro/.env.test.tpl +1 -0
- package/dist/init/templates/nitro/nitro.config.ts.tpl +12 -3
- package/dist/init/test/action.js +15 -0
- package/dist/init/test/create.js +100 -0
- package/dist/init/test/fill.js +26 -0
- package/dist/init/test/lookup.js +189 -0
- package/dist/init/test/run.js +26 -0
- package/dist/init/test/utils.js +17 -0
- package/dist/init/webframeworks.js +31 -28
- package/dist/mod.js +4 -2
- package/dist/nodeinfo.js +6 -6
- package/dist/utils.js +75 -8
- package/package.json +5 -5
- package/src/inbox.tsx +1 -15
- package/src/init/action/configs.ts +56 -13
- package/src/init/action/const.ts +9 -0
- package/src/init/action/deps.ts +98 -30
- package/src/init/action/install.ts +17 -52
- package/src/init/action/notice.ts +16 -14
- package/src/init/action/patch.ts +48 -27
- package/src/init/action/precommand.ts +9 -2
- package/src/init/action/set.ts +2 -15
- package/src/init/action/templates.ts +3 -2
- package/src/init/action/utils.ts +1 -1
- package/src/init/ask/kv.ts +64 -21
- package/src/init/ask/mq.ts +69 -20
- package/src/init/command.ts +39 -1
- package/src/init/lib.ts +31 -28
- package/src/init/mod.ts +2 -1
- package/src/init/templates/nitro/.env.test.tpl +1 -0
- package/src/init/templates/nitro/nitro.config.ts.tpl +12 -3
- package/src/init/test/action.ts +25 -0
- package/src/init/test/create.ts +137 -0
- package/src/init/test/fill.ts +61 -0
- package/src/init/test/lookup.ts +253 -0
- package/src/init/test/run.ts +42 -0
- package/src/init/test/types.ts +34 -0
- package/src/init/test/utils.ts +21 -0
- package/src/init/types.ts +4 -3
- package/src/init/webframeworks.ts +35 -18
- package/src/mod.ts +10 -1
- package/src/nodeinfo.ts +2 -1
- package/src/utils.ts +128 -10
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
getNextInitCommand,
|
|
7
7
|
getNitroInitCommand,
|
|
8
8
|
PACKAGE_VERSION,
|
|
9
|
+
packageManagerToRuntime,
|
|
9
10
|
readTemplate,
|
|
10
11
|
} from "./lib.ts";
|
|
11
12
|
import type { WebFrameworks } from "./types.ts";
|
|
@@ -14,21 +15,27 @@ const webFrameworks: WebFrameworks = {
|
|
|
14
15
|
hono: {
|
|
15
16
|
label: "Hono",
|
|
16
17
|
packageManagers: PACKAGE_MANAGER,
|
|
17
|
-
init: (projectName, pm) => ({
|
|
18
|
+
init: ({ projectName, packageManager: pm }) => ({
|
|
18
19
|
dependencies: pm === "deno"
|
|
19
20
|
? {
|
|
20
21
|
"@std/dotenv": "^0.225.2",
|
|
21
22
|
"@hono/hono": "^4.5.0",
|
|
22
23
|
"@hongminhee/x-forwarded-fetch": "^0.2.0",
|
|
24
|
+
"@fedify/hono": PACKAGE_VERSION,
|
|
23
25
|
}
|
|
24
26
|
: pm === "bun"
|
|
25
|
-
? {
|
|
27
|
+
? {
|
|
28
|
+
hono: "^4.5.0",
|
|
29
|
+
"x-forwarded-fetch": "^0.2.0",
|
|
30
|
+
"@fedify/hono": PACKAGE_VERSION,
|
|
31
|
+
}
|
|
26
32
|
: {
|
|
27
33
|
"@dotenvx/dotenvx": "^1.14.1",
|
|
28
34
|
hono: "^4.5.0",
|
|
29
35
|
"@hono/node-server": "^1.12.0",
|
|
30
36
|
tsx: "^4.17.0",
|
|
31
37
|
"x-forwarded-fetch": "^0.2.0",
|
|
38
|
+
"@fedify/hono": PACKAGE_VERSION,
|
|
32
39
|
},
|
|
33
40
|
devDependencies: pm === "bun" ? { "@types/bun": "^1.1.6" } : {},
|
|
34
41
|
federationFile: "src/federation.ts",
|
|
@@ -37,13 +44,12 @@ const webFrameworks: WebFrameworks = {
|
|
|
37
44
|
"src/app.tsx": pipe(
|
|
38
45
|
"hono/app.tsx",
|
|
39
46
|
readTemplate,
|
|
40
|
-
replace(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"src/index.ts": readTemplate(`hono/index/${pm}.ts`),
|
|
47
|
+
replace(/\/\* hono \*\//, pm === "deno" ? "@hono/hono" : "hono"),
|
|
48
|
+
replace(/\/\* logger \*\//, projectName),
|
|
49
|
+
),
|
|
50
|
+
"src/index.ts": readTemplate(
|
|
51
|
+
`hono/index/${packageManagerToRuntime(pm)}.ts`,
|
|
52
|
+
),
|
|
47
53
|
},
|
|
48
54
|
compilerOptions: pm === "deno" ? undefined : {
|
|
49
55
|
"lib": ["ESNext", "DOM"],
|
|
@@ -69,15 +75,16 @@ const webFrameworks: WebFrameworks = {
|
|
|
69
75
|
? "bun run ./src/index.ts"
|
|
70
76
|
: "dotenvx run -- node --import tsx ./src/index.ts",
|
|
71
77
|
},
|
|
72
|
-
instruction: getInstruction(pm),
|
|
78
|
+
instruction: getInstruction(pm, 8000),
|
|
73
79
|
}),
|
|
80
|
+
defaultPort: 8000,
|
|
74
81
|
},
|
|
75
82
|
express: {
|
|
76
83
|
label: "Express",
|
|
77
|
-
packageManagers:
|
|
78
|
-
init: (projectName, pm) => ({
|
|
84
|
+
packageManagers: PACKAGE_MANAGER,
|
|
85
|
+
init: ({ projectName, packageManager: pm }) => ({
|
|
79
86
|
dependencies: {
|
|
80
|
-
express: "^4.19.2",
|
|
87
|
+
"npm:express": "^4.19.2",
|
|
81
88
|
"@fedify/express": PACKAGE_VERSION,
|
|
82
89
|
...(pm !== "deno" && pm !== "bun"
|
|
83
90
|
? { "@dotenvx/dotenvx": "^1.14.1", tsx: "^4.17.0" }
|
|
@@ -107,18 +114,23 @@ const webFrameworks: WebFrameworks = {
|
|
|
107
114
|
tasks: {
|
|
108
115
|
"dev": pm === "bun"
|
|
109
116
|
? "bun run --hot ./src/index.ts"
|
|
117
|
+
: pm === "deno"
|
|
118
|
+
? "deno run --allow-net --allow-env --allow-sys --watch ./src/index.ts"
|
|
110
119
|
: "dotenvx run -- tsx watch ./src/index.ts",
|
|
111
120
|
"prod": pm === "bun"
|
|
112
121
|
? "bun run ./src/index.ts"
|
|
122
|
+
: pm === "deno"
|
|
123
|
+
? "deno run --allow-net --allow-env --allow-sys ./src/index.ts"
|
|
113
124
|
: "dotenvx run -- node --import tsx ./src/index.ts",
|
|
114
125
|
},
|
|
115
|
-
instruction: getInstruction(pm),
|
|
126
|
+
instruction: getInstruction(pm, 8000),
|
|
116
127
|
}),
|
|
128
|
+
defaultPort: 8000,
|
|
117
129
|
},
|
|
118
130
|
nitro: {
|
|
119
131
|
label: "Nitro",
|
|
120
132
|
packageManagers: PACKAGE_MANAGER,
|
|
121
|
-
init: (
|
|
133
|
+
init: ({ packageManager: pm, testMode }) => ({
|
|
122
134
|
command: getNitroInitCommand(pm),
|
|
123
135
|
dependencies: { "@fedify/h3": PACKAGE_VERSION },
|
|
124
136
|
federationFile: "server/federation.ts",
|
|
@@ -129,14 +141,18 @@ const webFrameworks: WebFrameworks = {
|
|
|
129
141
|
),
|
|
130
142
|
"server/error.ts": readTemplate("nitro/server/error.ts"),
|
|
131
143
|
"nitro.config.ts": readTemplate("nitro/nitro.config.ts"),
|
|
144
|
+
...(
|
|
145
|
+
testMode ? { ".env": readTemplate("nitro/.env.test") } : {}
|
|
146
|
+
),
|
|
132
147
|
},
|
|
133
|
-
instruction: getInstruction(pm),
|
|
148
|
+
instruction: getInstruction(pm, 3000),
|
|
134
149
|
}),
|
|
150
|
+
defaultPort: 3000,
|
|
135
151
|
},
|
|
136
152
|
next: {
|
|
137
153
|
label: "Next.js",
|
|
138
154
|
packageManagers: PACKAGE_MANAGER,
|
|
139
|
-
init: (
|
|
155
|
+
init: ({ packageManager: pm }) => ({
|
|
140
156
|
label: "Next.js",
|
|
141
157
|
command: getNextInitCommand(pm),
|
|
142
158
|
dependencies: { "@fedify/next": PACKAGE_VERSION },
|
|
@@ -144,8 +160,9 @@ const webFrameworks: WebFrameworks = {
|
|
|
144
160
|
federationFile: "federation/index.ts",
|
|
145
161
|
loggingFile: "logging.ts",
|
|
146
162
|
files: { "middleware.ts": readTemplate("next/middleware.ts") },
|
|
147
|
-
instruction: getInstruction(pm),
|
|
163
|
+
instruction: getInstruction(pm, 3000),
|
|
148
164
|
}),
|
|
165
|
+
defaultPort: 3000,
|
|
149
166
|
},
|
|
150
167
|
} as const;
|
|
151
168
|
export default webFrameworks;
|
package/src/mod.ts
CHANGED
|
@@ -6,7 +6,12 @@ import {
|
|
|
6
6
|
runGenerateVocab,
|
|
7
7
|
} from "./generate-vocab/mod.ts";
|
|
8
8
|
import { inboxCommand, runInbox } from "./inbox.tsx";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
initCommand,
|
|
11
|
+
runInit,
|
|
12
|
+
runTestInit,
|
|
13
|
+
testInitCommand,
|
|
14
|
+
} from "./init/mod.ts";
|
|
10
15
|
import { lookupCommand, runLookup } from "./lookup.ts";
|
|
11
16
|
import { nodeInfoCommand, runNodeInfo } from "./nodeinfo.ts";
|
|
12
17
|
import { runTunnel, tunnelCommand } from "./tunnel.ts";
|
|
@@ -20,6 +25,7 @@ const command = or(
|
|
|
20
25
|
nodeInfoCommand,
|
|
21
26
|
tunnelCommand,
|
|
22
27
|
generateVocabCommand,
|
|
28
|
+
testInitCommand,
|
|
23
29
|
);
|
|
24
30
|
|
|
25
31
|
async function main() {
|
|
@@ -48,6 +54,9 @@ async function main() {
|
|
|
48
54
|
if (result.command === "generate-vocab") {
|
|
49
55
|
await runGenerateVocab(result);
|
|
50
56
|
}
|
|
57
|
+
if (result.command === "test-init") {
|
|
58
|
+
await runTestInit(result);
|
|
59
|
+
}
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
await main();
|
package/src/nodeinfo.ts
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
optional,
|
|
17
17
|
or,
|
|
18
18
|
string,
|
|
19
|
+
text,
|
|
19
20
|
} from "@optique/core";
|
|
20
21
|
import { print, printError } from "@optique/run";
|
|
21
22
|
import type { ChalkInstance } from "chalk";
|
|
@@ -111,7 +112,7 @@ export async function runNodeInfo(
|
|
|
111
112
|
}
|
|
112
113
|
spinner.succeed("NodeInfo document fetched.");
|
|
113
114
|
|
|
114
|
-
|
|
115
|
+
print(message`${text(formatObject(nodeInfo, undefined, true))}`);
|
|
115
116
|
return;
|
|
116
117
|
}
|
|
117
118
|
const nodeInfo = await getNodeInfo(url, {
|
package/src/utils.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { isObject } from "@fxts/core";
|
|
2
|
+
import { message } from "@optique/core";
|
|
3
|
+
import { print, printError } from "@optique/run";
|
|
2
4
|
import { Chalk } from "chalk";
|
|
3
5
|
import { highlight } from "cli-highlight";
|
|
4
|
-
import { toMerged } from "es-toolkit";
|
|
6
|
+
import { flow, toMerged } from "es-toolkit";
|
|
5
7
|
import { spawn } from "node:child_process";
|
|
6
8
|
import { writeFile } from "node:fs/promises";
|
|
7
9
|
import process from "node:process";
|
|
@@ -59,18 +61,68 @@ export const isNotFoundError = (e: unknown): e is { code: "ENOENT" } =>
|
|
|
59
61
|
"code" in e &&
|
|
60
62
|
e.code === "ENOENT";
|
|
61
63
|
|
|
62
|
-
export
|
|
64
|
+
export class CommandError extends Error {
|
|
65
|
+
public commandLine: string;
|
|
66
|
+
constructor(
|
|
67
|
+
message: string,
|
|
68
|
+
public stdout: string,
|
|
69
|
+
public stderr: string,
|
|
70
|
+
public code: number,
|
|
71
|
+
public command: string[],
|
|
72
|
+
) {
|
|
73
|
+
super(message);
|
|
74
|
+
this.name = "CommandError";
|
|
75
|
+
this.commandLine = command.join(" ");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const runSubCommand = async <Opt extends Parameters<typeof spawn>[2]>(
|
|
63
80
|
command: string[],
|
|
64
81
|
options: Opt,
|
|
65
82
|
): Promise<{
|
|
66
83
|
stdout: string;
|
|
67
84
|
stderr: string;
|
|
68
|
-
}> =>
|
|
69
|
-
|
|
70
|
-
|
|
85
|
+
}> => {
|
|
86
|
+
const commands = // split by "&&"
|
|
87
|
+
command.reduce<string[][]>((acc, cur) => {
|
|
88
|
+
if (cur === "&&") {
|
|
89
|
+
acc.push([]);
|
|
90
|
+
} else {
|
|
91
|
+
if (acc.length === 0) acc.push([]);
|
|
92
|
+
acc[acc.length - 1].push(cur);
|
|
93
|
+
}
|
|
94
|
+
return acc;
|
|
95
|
+
}, []);
|
|
96
|
+
|
|
97
|
+
const results = { stdout: "", stderr: "" };
|
|
98
|
+
|
|
99
|
+
for (const cmd of commands) {
|
|
100
|
+
try {
|
|
101
|
+
const result = await runSingularCommand(cmd, options);
|
|
102
|
+
results.stdout += (results.stdout ? "\n" : "") + result.stdout;
|
|
103
|
+
results.stderr += (results.stderr ? "\n" : "") + result.stderr;
|
|
104
|
+
} catch (e) {
|
|
105
|
+
if (e instanceof CommandError) {
|
|
106
|
+
results.stdout += (results.stdout ? "\n" : "") + e.stdout;
|
|
107
|
+
results.stderr += (results.stderr ? "\n" : "") + e.stderr;
|
|
108
|
+
}
|
|
109
|
+
throw e;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return results;
|
|
113
|
+
};
|
|
71
114
|
|
|
115
|
+
const runSingularCommand = (
|
|
116
|
+
command: string[],
|
|
117
|
+
options: Parameters<typeof spawn>[2],
|
|
118
|
+
) =>
|
|
119
|
+
new Promise<{
|
|
120
|
+
stdout: string;
|
|
121
|
+
stderr: string;
|
|
122
|
+
}>((resolve, reject) => {
|
|
72
123
|
let stdout = "";
|
|
73
124
|
let stderr = "";
|
|
125
|
+
const child = spawn(command[0], command.slice(1), options);
|
|
74
126
|
|
|
75
127
|
child.stdout?.on("data", (data) => {
|
|
76
128
|
stdout += data.toString();
|
|
@@ -79,11 +131,23 @@ export const runSubCommand = <Opt extends Parameters<typeof spawn>[2]>(
|
|
|
79
131
|
stderr += data.toString();
|
|
80
132
|
});
|
|
81
133
|
|
|
82
|
-
child.on("close", () => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
134
|
+
child.on("close", (code) => {
|
|
135
|
+
if (code === 0) {
|
|
136
|
+
resolve({
|
|
137
|
+
stdout: stdout.trim(),
|
|
138
|
+
stderr: stderr.trim(),
|
|
139
|
+
});
|
|
140
|
+
} else {
|
|
141
|
+
reject(
|
|
142
|
+
new CommandError(
|
|
143
|
+
`Command exited with code ${code ?? "unknown"}`,
|
|
144
|
+
stdout.trim(),
|
|
145
|
+
stderr.trim(),
|
|
146
|
+
code ?? -1,
|
|
147
|
+
command,
|
|
148
|
+
),
|
|
149
|
+
);
|
|
150
|
+
}
|
|
87
151
|
});
|
|
88
152
|
|
|
89
153
|
child.on("error", (error) => {
|
|
@@ -103,6 +167,12 @@ export const replace = (
|
|
|
103
167
|
) =>
|
|
104
168
|
(text: string): string => text.replace(pattern, replacement as string);
|
|
105
169
|
|
|
170
|
+
export const replaceAll = (
|
|
171
|
+
pattern: string | RegExp,
|
|
172
|
+
replacement: string | ((substring: string, ...args: unknown[]) => string),
|
|
173
|
+
) =>
|
|
174
|
+
(text: string): string => text.replaceAll(pattern, replacement as string);
|
|
175
|
+
|
|
106
176
|
export const getOsType = () => process.platform;
|
|
107
177
|
|
|
108
178
|
export async function writeTextFile(
|
|
@@ -134,3 +204,51 @@ export const notEmptyObj = <T extends Record<PropertyKey, never> | object>(
|
|
|
134
204
|
): obj is Exclude<T, Record<PropertyKey, never>> => Object.keys(obj).length > 0;
|
|
135
205
|
|
|
136
206
|
export const exit = (code: number) => process.exit(code);
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Generic type to represent the types of the items in iterables.
|
|
210
|
+
*/
|
|
211
|
+
export type ItersItems<T extends Iterable<unknown>[]> = T extends [] ? []
|
|
212
|
+
: T extends [infer Head, ...infer Tail]
|
|
213
|
+
? Head extends Iterable<infer Item>
|
|
214
|
+
? Tail extends Iterable<unknown>[] ? [Item, ...ItersItems<Tail>]
|
|
215
|
+
: [Item]
|
|
216
|
+
: never
|
|
217
|
+
: never;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* ```haskell
|
|
221
|
+
* product::[[a], [b], ...] -> [[a, b, ...]]
|
|
222
|
+
* ```
|
|
223
|
+
*
|
|
224
|
+
* Cartesian product of the input iterables.
|
|
225
|
+
* Inspired by Python's `itertools.product`.
|
|
226
|
+
*
|
|
227
|
+
* @param {...Iterable<unknown>} iters - The input iterables to compute the Cartesian product.
|
|
228
|
+
* @returns {Generator<ItersItems<T>>} A generator that yields arrays containing one element from each iterable.
|
|
229
|
+
*
|
|
230
|
+
* @example
|
|
231
|
+
* ```ts
|
|
232
|
+
* const iter1 = [1, 2];
|
|
233
|
+
* const iter2 = ['a', 'b'];
|
|
234
|
+
* const iter3 = [true, false];
|
|
235
|
+
* const productIter = product(iter1, iter2, iter3);
|
|
236
|
+
* console.log(Array.from(productIter)); // Output: [[1, 'a', true], [1, 'a', false], [
|
|
237
|
+
*/
|
|
238
|
+
export function* product<T extends Iterable<unknown>[]>(
|
|
239
|
+
...[head, ...tail]: T
|
|
240
|
+
): Generator<ItersItems<T>> {
|
|
241
|
+
if (!head) yield [] as ItersItems<T>;
|
|
242
|
+
else {
|
|
243
|
+
for (const x of head) {
|
|
244
|
+
for (const xs of product(...tail)) yield [x, ...xs] as ItersItems<T>;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export type GeneratedType<T extends Generator> = T extends
|
|
250
|
+
Generator<unknown, infer R, unknown> ? R : never;
|
|
251
|
+
|
|
252
|
+
type PrintMessage = (...args: Parameters<typeof message>) => void;
|
|
253
|
+
export const printMessage: PrintMessage = flow(message, print);
|
|
254
|
+
export const printErrorMessage: PrintMessage = flow(message, printError);
|