@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
package/dist/mod.js
CHANGED
|
@@ -7,7 +7,8 @@ import command_default from "./generate-vocab/command.js";
|
|
|
7
7
|
import "./generate-vocab/mod.js";
|
|
8
8
|
import { inboxCommand, runInbox } from "./inbox.js";
|
|
9
9
|
import action_default from "./init/action/mod.js";
|
|
10
|
-
import { initCommand } from "./init/command.js";
|
|
10
|
+
import { initCommand, testInitCommand } from "./init/command.js";
|
|
11
|
+
import action_default$1 from "./init/test/action.js";
|
|
11
12
|
import "./init/mod.js";
|
|
12
13
|
import { nodeInfoCommand, runNodeInfo } from "./nodeinfo.js";
|
|
13
14
|
import { lookupCommand, runLookup } from "./lookup.js";
|
|
@@ -19,7 +20,7 @@ import { or } from "@optique/core";
|
|
|
19
20
|
import { run } from "@optique/run";
|
|
20
21
|
|
|
21
22
|
//#region src/mod.ts
|
|
22
|
-
const command$1 = or(initCommand, webFingerCommand, lookupCommand, inboxCommand, nodeInfoCommand, tunnelCommand, command_default);
|
|
23
|
+
const command$1 = or(initCommand, webFingerCommand, lookupCommand, inboxCommand, nodeInfoCommand, tunnelCommand, command_default, testInitCommand);
|
|
23
24
|
async function main() {
|
|
24
25
|
const result = run(command$1, {
|
|
25
26
|
programName: "fedify",
|
|
@@ -32,6 +33,7 @@ async function main() {
|
|
|
32
33
|
if (result.command === "nodeinfo") runNodeInfo(result);
|
|
33
34
|
if (result.command === "tunnel") await runTunnel(result);
|
|
34
35
|
if (result.command === "generate-vocab") await runGenerateVocab(result);
|
|
36
|
+
if (result.command === "test-init") await action_default$1(result);
|
|
35
37
|
}
|
|
36
38
|
await main();
|
|
37
39
|
|
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 } from "@optique/core";
|
|
6
|
+
import { argument, command, constant, flag, merge, message, object, option, optional, or, string, text } 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
|
-
|
|
61
|
+
print(message`${text(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, depth) {
|
|
157
|
-
return text.replace(/\n/g, "\n" + " ".repeat(depth));
|
|
156
|
+
function indent(text$1, depth) {
|
|
157
|
+
return text$1.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 = await response.text();
|
|
164
|
-
for (const match of text.matchAll(LINK_REGEXP)) {
|
|
163
|
+
const text$1 = await response.text();
|
|
164
|
+
for (const match of text$1.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/dist/utils.js
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
import { Temporal } from "@js-temporal/polyfill";
|
|
3
3
|
|
|
4
4
|
import { writeFile } from "node:fs/promises";
|
|
5
|
+
import { message } from "@optique/core";
|
|
6
|
+
import { print, printError } from "@optique/run";
|
|
5
7
|
import process from "node:process";
|
|
6
8
|
import util from "node:util";
|
|
7
9
|
import { isObject } from "@fxts/core";
|
|
8
10
|
import { Chalk } from "chalk";
|
|
9
11
|
import { highlight } from "cli-highlight";
|
|
10
|
-
import { toMerged } from "es-toolkit";
|
|
12
|
+
import { flow, toMerged } from "es-toolkit";
|
|
11
13
|
import { spawn } from "node:child_process";
|
|
12
14
|
|
|
13
15
|
//#region src/utils.ts
|
|
@@ -34,34 +36,99 @@ function set(key, f) {
|
|
|
34
36
|
};
|
|
35
37
|
};
|
|
36
38
|
}
|
|
37
|
-
const merge = (source = {}) => (target = {}) => toMerged(target, source);
|
|
39
|
+
const merge$1 = (source = {}) => (target = {}) => toMerged(target, source);
|
|
38
40
|
const isNotFoundError = (e) => isObject(e) && "code" in e && e.code === "ENOENT";
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
var CommandError = class extends Error {
|
|
42
|
+
commandLine;
|
|
43
|
+
constructor(message$1, stdout, stderr, code, command$1) {
|
|
44
|
+
super(message$1);
|
|
45
|
+
this.stdout = stdout;
|
|
46
|
+
this.stderr = stderr;
|
|
47
|
+
this.code = code;
|
|
48
|
+
this.command = command$1;
|
|
49
|
+
this.name = "CommandError";
|
|
50
|
+
this.commandLine = command$1.join(" ");
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const runSubCommand = async (command$1, options) => {
|
|
54
|
+
const commands = command$1.reduce((acc, cur) => {
|
|
55
|
+
if (cur === "&&") acc.push([]);
|
|
56
|
+
else {
|
|
57
|
+
if (acc.length === 0) acc.push([]);
|
|
58
|
+
acc[acc.length - 1].push(cur);
|
|
59
|
+
}
|
|
60
|
+
return acc;
|
|
61
|
+
}, []);
|
|
62
|
+
const results = {
|
|
63
|
+
stdout: "",
|
|
64
|
+
stderr: ""
|
|
65
|
+
};
|
|
66
|
+
for (const cmd of commands) try {
|
|
67
|
+
const result = await runSingularCommand(cmd, options);
|
|
68
|
+
results.stdout += (results.stdout ? "\n" : "") + result.stdout;
|
|
69
|
+
results.stderr += (results.stderr ? "\n" : "") + result.stderr;
|
|
70
|
+
} catch (e) {
|
|
71
|
+
if (e instanceof CommandError) {
|
|
72
|
+
results.stdout += (results.stdout ? "\n" : "") + e.stdout;
|
|
73
|
+
results.stderr += (results.stderr ? "\n" : "") + e.stderr;
|
|
74
|
+
}
|
|
75
|
+
throw e;
|
|
76
|
+
}
|
|
77
|
+
return results;
|
|
78
|
+
};
|
|
79
|
+
const runSingularCommand = (command$1, options) => new Promise((resolve, reject) => {
|
|
41
80
|
let stdout = "";
|
|
42
81
|
let stderr = "";
|
|
82
|
+
const child = spawn(command$1[0], command$1.slice(1), options);
|
|
43
83
|
child.stdout?.on("data", (data) => {
|
|
44
84
|
stdout += data.toString();
|
|
45
85
|
});
|
|
46
86
|
child.stderr?.on("data", (data) => {
|
|
47
87
|
stderr += data.toString();
|
|
48
88
|
});
|
|
49
|
-
child.on("close", () => {
|
|
50
|
-
resolve({
|
|
89
|
+
child.on("close", (code) => {
|
|
90
|
+
if (code === 0) resolve({
|
|
51
91
|
stdout: stdout.trim(),
|
|
52
92
|
stderr: stderr.trim()
|
|
53
93
|
});
|
|
94
|
+
else reject(new CommandError(`Command exited with code ${code ?? "unknown"}`, stdout.trim(), stderr.trim(), code ?? -1, command$1));
|
|
54
95
|
});
|
|
55
96
|
child.on("error", (error) => {
|
|
56
97
|
reject(error);
|
|
57
98
|
});
|
|
58
99
|
});
|
|
59
100
|
const getCwd = () => process.cwd();
|
|
60
|
-
const replace = (pattern, replacement) => (text) => text.replace(pattern, replacement);
|
|
101
|
+
const replace = (pattern, replacement) => (text$1) => text$1.replace(pattern, replacement);
|
|
102
|
+
const replaceAll = (pattern, replacement) => (text$1) => text$1.replaceAll(pattern, replacement);
|
|
61
103
|
const getOsType = () => process.platform;
|
|
62
104
|
const formatJson = (obj) => JSON.stringify(obj, null, 2) + "\n";
|
|
63
105
|
const notEmpty = (s) => s.length > 0;
|
|
64
106
|
const exit = (code) => process.exit(code);
|
|
107
|
+
/**
|
|
108
|
+
* ```haskell
|
|
109
|
+
* product::[[a], [b], ...] -> [[a, b, ...]]
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
112
|
+
* Cartesian product of the input iterables.
|
|
113
|
+
* Inspired by Python's `itertools.product`.
|
|
114
|
+
*
|
|
115
|
+
* @param {...Iterable<unknown>} iters - The input iterables to compute the Cartesian product.
|
|
116
|
+
* @returns {Generator<ItersItems<T>>} A generator that yields arrays containing one element from each iterable.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* const iter1 = [1, 2];
|
|
121
|
+
* const iter2 = ['a', 'b'];
|
|
122
|
+
* const iter3 = [true, false];
|
|
123
|
+
* const productIter = product(iter1, iter2, iter3);
|
|
124
|
+
* console.log(Array.from(productIter)); // Output: [[1, 'a', true], [1, 'a', false], [
|
|
125
|
+
*/
|
|
126
|
+
function* product(...[head, ...tail]) {
|
|
127
|
+
if (!head) yield [];
|
|
128
|
+
else for (const x of head) for (const xs of product(...tail)) yield [x, ...xs];
|
|
129
|
+
}
|
|
130
|
+
const printMessage = flow(message, print);
|
|
131
|
+
const printErrorMessage = flow(message, printError);
|
|
65
132
|
|
|
66
133
|
//#endregion
|
|
67
|
-
export { colorEnabled, colors, exit, formatJson, formatObject, getCwd, getOsType, isNotFoundError, merge, notEmpty, replace, runSubCommand, set };
|
|
134
|
+
export { CommandError, colorEnabled, colors, exit, formatJson, formatObject, getCwd, getOsType, isNotFoundError, merge$1 as merge, notEmpty, printErrorMessage, printMessage, product, replace, replaceAll, runSubCommand, set };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/cli",
|
|
3
|
-
"version": "2.0.0-pr.
|
|
3
|
+
"version": "2.0.0-pr.479.1900+0b40bf02",
|
|
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/
|
|
75
|
-
"@fedify/
|
|
76
|
-
"@fedify/vocab-tools": "2.0.0-pr.
|
|
77
|
-
"@fedify/
|
|
74
|
+
"@fedify/sqlite": "2.0.0-pr.479.1900+0b40bf02",
|
|
75
|
+
"@fedify/fedify": "2.0.0-pr.479.1900+0b40bf02",
|
|
76
|
+
"@fedify/vocab-tools": "2.0.0-pr.479.1900+0b40bf02",
|
|
77
|
+
"@fedify/vocab-runtime": "2.0.0-pr.479.1900+0b40bf02"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@types/bun": "^1.2.23",
|
package/src/inbox.tsx
CHANGED
|
@@ -103,14 +103,6 @@ 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
|
-
),
|
|
114
106
|
}),
|
|
115
107
|
debugOption,
|
|
116
108
|
),
|
|
@@ -127,7 +119,6 @@ export async function runInbox(
|
|
|
127
119
|
const fetch = createFetchHandler({
|
|
128
120
|
actorName: command.actorName,
|
|
129
121
|
actorSummary: command.actorSummary,
|
|
130
|
-
requireHttpSignature: command.authorizedFetch,
|
|
131
122
|
});
|
|
132
123
|
const sendDeleteToPeers = createSendDeleteToPeers({
|
|
133
124
|
actorName: command.actorName,
|
|
@@ -508,11 +499,7 @@ app.get("/r/:idx{[0-9]+}", (c) => {
|
|
|
508
499
|
});
|
|
509
500
|
|
|
510
501
|
function createFetchHandler(
|
|
511
|
-
actorOptions: {
|
|
512
|
-
actorName: string;
|
|
513
|
-
actorSummary: string;
|
|
514
|
-
requireHttpSignature?: boolean;
|
|
515
|
-
},
|
|
502
|
+
actorOptions: { actorName: string; actorSummary: string },
|
|
516
503
|
): (request: Request) => Promise<Response> {
|
|
517
504
|
return async function fetch(request: Request): Promise<Response> {
|
|
518
505
|
const timestamp = Temporal.Now.instant();
|
|
@@ -534,7 +521,6 @@ function createFetchHandler(
|
|
|
534
521
|
actorName: actorOptions.actorName,
|
|
535
522
|
actorSummary: actorOptions.actorSummary,
|
|
536
523
|
},
|
|
537
|
-
requireHttpSignature: actorOptions.requireHttpSignature,
|
|
538
524
|
onNotAcceptable: app.fetch.bind(app),
|
|
539
525
|
onNotFound: app.fetch.bind(app),
|
|
540
526
|
onUnauthorized: app.fetch.bind(app),
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
concat,
|
|
3
|
+
filter,
|
|
4
|
+
keys,
|
|
5
|
+
map,
|
|
6
|
+
pick,
|
|
7
|
+
pipe,
|
|
8
|
+
toArray,
|
|
9
|
+
} from "@fxts/core/index.js";
|
|
10
|
+
import { uniq } from "es-toolkit";
|
|
11
|
+
import { join as joinPath, relative } from "node:path";
|
|
12
|
+
import { merge } from "../../utils.ts";
|
|
2
13
|
import biome from "../json/biome.json" with { type: "json" };
|
|
3
14
|
import vscodeSettingsForDeno from "../json/vscode-settings-for-deno.json" with {
|
|
4
15
|
type: "json",
|
|
@@ -7,6 +18,8 @@ import vscodeSettings from "../json/vscode-settings.json" with {
|
|
|
7
18
|
type: "json",
|
|
8
19
|
};
|
|
9
20
|
import type { InitCommandData } from "../types.ts";
|
|
21
|
+
import { PACKAGES_PATH } from "./const.ts";
|
|
22
|
+
import { getDependencies, getDevDependencies, joinDepsReg } from "./deps.ts";
|
|
10
23
|
|
|
11
24
|
/**
|
|
12
25
|
* Loads Deno configuration object with compiler options, unstable features, and tasks.
|
|
@@ -16,20 +29,46 @@ import type { InitCommandData } from "../types.ts";
|
|
|
16
29
|
* @returns Configuration object with path and Deno-specific settings
|
|
17
30
|
*/
|
|
18
31
|
export const loadDenoConfig = (
|
|
19
|
-
|
|
32
|
+
data: InitCommandData,
|
|
20
33
|
) => ({
|
|
21
|
-
path:
|
|
34
|
+
path: "deno.json",
|
|
22
35
|
data: {
|
|
23
|
-
compilerOptions
|
|
36
|
+
...pick(["compilerOptions", "tasks"], data.initializer),
|
|
37
|
+
unstable: getUnstable(data),
|
|
38
|
+
nodeModulesDir: "auto",
|
|
39
|
+
imports: joinDepsReg("deno")(getDependencies(data)),
|
|
40
|
+
...(data.testMode ? { links: getLinks(data) } : {}),
|
|
24
41
|
},
|
|
25
|
-
unstable: [
|
|
26
|
-
"temporal",
|
|
27
|
-
...kv.denoUnstable ?? [],
|
|
28
|
-
...mq.denoUnstable ?? [],
|
|
29
|
-
],
|
|
30
|
-
tasks: initializer.tasks,
|
|
31
42
|
});
|
|
32
43
|
|
|
44
|
+
const getUnstable = <T extends Pick<InitCommandData, "kv" | "mq">>({
|
|
45
|
+
kv: { denoUnstable: kv = [] },
|
|
46
|
+
mq: { denoUnstable: mq = [] },
|
|
47
|
+
}: T) =>
|
|
48
|
+
pipe(
|
|
49
|
+
["temporal"],
|
|
50
|
+
concat(kv),
|
|
51
|
+
concat(mq),
|
|
52
|
+
toArray,
|
|
53
|
+
uniq,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const getLinks = <
|
|
57
|
+
T extends Pick<InitCommandData, "kv" | "mq" | "initializer" | "dir">,
|
|
58
|
+
>({ kv, mq, initializer, dir }: T) =>
|
|
59
|
+
pipe(
|
|
60
|
+
{ "@fedify/fedify": "" },
|
|
61
|
+
merge(initializer.dependencies),
|
|
62
|
+
merge(kv.dependencies),
|
|
63
|
+
merge(mq.dependencies),
|
|
64
|
+
keys,
|
|
65
|
+
filter((dep) => dep.includes("@fedify/")),
|
|
66
|
+
map((dep) => dep.replace("@fedify/", "")),
|
|
67
|
+
map((dep) => joinPath(PACKAGES_PATH, dep)),
|
|
68
|
+
map((absolutePath) => relative(dir, absolutePath)),
|
|
69
|
+
toArray,
|
|
70
|
+
);
|
|
71
|
+
|
|
33
72
|
/**
|
|
34
73
|
* Loads TypeScript configuration object for Node.js/Bun projects.
|
|
35
74
|
* Uses compiler options from the framework initializer.
|
|
@@ -51,11 +90,15 @@ export const loadTsConfig = ({ initializer, dir }: InitCommandData) => ({
|
|
|
51
90
|
* @param param0 - Destructured initialization data containing initializer and directory
|
|
52
91
|
* @returns Configuration object with path and package.json settings
|
|
53
92
|
*/
|
|
54
|
-
export const loadPackageJson = (
|
|
55
|
-
|
|
93
|
+
export const loadPackageJson = (
|
|
94
|
+
data: InitCommandData,
|
|
95
|
+
) => ({
|
|
96
|
+
path: "package.json",
|
|
56
97
|
data: {
|
|
57
98
|
type: "module",
|
|
58
|
-
scripts: initializer.tasks,
|
|
99
|
+
scripts: data.initializer.tasks,
|
|
100
|
+
dependencies: getDependencies(data),
|
|
101
|
+
devDependencies: getDevDependencies(data),
|
|
59
102
|
},
|
|
60
103
|
});
|
|
61
104
|
|
package/src/init/action/deps.ts
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
always,
|
|
3
|
+
entries,
|
|
4
|
+
filter,
|
|
5
|
+
fromEntries,
|
|
6
|
+
map,
|
|
7
|
+
pipe,
|
|
8
|
+
when,
|
|
9
|
+
} from "@fxts/core";
|
|
10
|
+
import { join as joinPath } from "node:path";
|
|
11
|
+
import { merge, replace } from "../../utils.ts";
|
|
3
12
|
import { PACKAGE_VERSION } from "../lib.ts";
|
|
4
13
|
import type { InitCommandData, PackageManager } from "../types.ts";
|
|
14
|
+
import { PACKAGES_PATH } from "./const.ts";
|
|
15
|
+
import { isDeno } from "./utils.ts";
|
|
5
16
|
|
|
6
17
|
type Deps = Record<string, string>;
|
|
7
18
|
|
|
@@ -9,11 +20,15 @@ type Deps = Record<string, string>;
|
|
|
9
20
|
* Gathers all dependencies required for the project based on the initializer,
|
|
10
21
|
* key-value store, and message queue configurations.
|
|
11
22
|
*
|
|
12
|
-
* @param data - Web Framework initializer, key-value store and
|
|
23
|
+
* @param data - Web Framework initializer, key-value store and
|
|
24
|
+
* message queue descriptions
|
|
13
25
|
* @returns A record of dependencies with their versions
|
|
14
26
|
*/
|
|
15
27
|
export const getDependencies = (
|
|
16
|
-
{ initializer, kv, mq }:
|
|
28
|
+
{ initializer, kv, mq, testMode, packageManager }: Pick<
|
|
29
|
+
InitCommandData,
|
|
30
|
+
"initializer" | "kv" | "mq" | "packageManager" | "testMode"
|
|
31
|
+
>,
|
|
17
32
|
): Deps =>
|
|
18
33
|
pipe(
|
|
19
34
|
{
|
|
@@ -23,16 +38,54 @@ export const getDependencies = (
|
|
|
23
38
|
merge(initializer.dependencies),
|
|
24
39
|
merge(kv.dependencies),
|
|
25
40
|
merge(mq.dependencies),
|
|
41
|
+
when(
|
|
42
|
+
always(testMode),
|
|
43
|
+
isDeno({ packageManager }) ? removeFedifyDeps : addLocalFedifyDeps,
|
|
44
|
+
),
|
|
45
|
+
normalizePackageNames(packageManager),
|
|
26
46
|
);
|
|
27
47
|
|
|
28
|
-
|
|
29
|
-
|
|
48
|
+
const removeFedifyDeps = (deps: Deps): Deps =>
|
|
49
|
+
pipe(
|
|
50
|
+
deps,
|
|
51
|
+
entries,
|
|
52
|
+
filter(([name]) => !name.includes("@fedify")),
|
|
53
|
+
fromEntries,
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
const addLocalFedifyDeps = (deps: Deps): Deps =>
|
|
57
|
+
pipe(
|
|
58
|
+
deps,
|
|
59
|
+
entries,
|
|
60
|
+
map(when(
|
|
61
|
+
([name]) => name.includes("@fedify/"),
|
|
62
|
+
(
|
|
63
|
+
[name, _version],
|
|
64
|
+
): [string, string] => [name, convertFedifyToLocal(name)],
|
|
65
|
+
)),
|
|
66
|
+
fromEntries,
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const convertFedifyToLocal = (name: string): string =>
|
|
70
|
+
pipe(
|
|
71
|
+
name,
|
|
72
|
+
replace("@fedify/", ""),
|
|
73
|
+
(pkg) => joinPath(PACKAGES_PATH, pkg),
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
/** Gathers all devDependencies required for the project based on the
|
|
77
|
+
* initializer, key-value store, and message queue configurations,
|
|
78
|
+
* including Biome for linting/formatting.
|
|
30
79
|
*
|
|
31
|
-
* @param data - Web Framework initializer, key-value store
|
|
80
|
+
* @param data - Web Framework initializer, key-value store
|
|
81
|
+
* and message queue descriptions
|
|
32
82
|
* @returns A record of devDependencies with their versions
|
|
33
83
|
*/
|
|
34
84
|
export const getDevDependencies = (
|
|
35
|
-
{ initializer, kv, mq }:
|
|
85
|
+
{ initializer, kv, mq, packageManager }: Pick<
|
|
86
|
+
InitCommandData,
|
|
87
|
+
"initializer" | "kv" | "mq" | "packageManager"
|
|
88
|
+
>,
|
|
36
89
|
): Deps =>
|
|
37
90
|
pipe(
|
|
38
91
|
{
|
|
@@ -41,14 +94,16 @@ export const getDevDependencies = (
|
|
|
41
94
|
merge(initializer.devDependencies),
|
|
42
95
|
merge(kv.devDependencies),
|
|
43
96
|
merge(mq.devDependencies),
|
|
97
|
+
normalizePackageNames(packageManager),
|
|
44
98
|
);
|
|
45
99
|
|
|
46
100
|
/**
|
|
47
|
-
* Generates the command-line arguments needed to add dependencies
|
|
48
|
-
* using the specified package manager.
|
|
101
|
+
* Generates the command-line arguments needed to add dependencies
|
|
102
|
+
* or devDependencies using the specified package manager.
|
|
49
103
|
* If it is devDependencies, the '-D' flag is included.
|
|
50
104
|
*
|
|
51
|
-
* @param param0 - Object containing the package manager and a boolean
|
|
105
|
+
* @param param0 - Object containing the package manager and a boolean
|
|
106
|
+
* indicating if dev dependencies are to be added
|
|
52
107
|
* @yields The command-line arguments as strings
|
|
53
108
|
*/
|
|
54
109
|
export function* getAddDepsArgs<
|
|
@@ -60,34 +115,47 @@ export function* getAddDepsArgs<
|
|
|
60
115
|
}
|
|
61
116
|
|
|
62
117
|
/**
|
|
63
|
-
* Joins package names with their versions for installation
|
|
64
|
-
* For Deno, it prefixes packages with 'jsr:'
|
|
118
|
+
* Joins package names with their versions for installation dependencies.
|
|
119
|
+
* For Deno, it prefixes packages with 'jsr:'
|
|
120
|
+
* unless they already start with 'npm:' or 'jsr:'.
|
|
65
121
|
*
|
|
66
122
|
* @param data - Package manager and dependencies to be joined with versions
|
|
67
|
-
* @returns `${registry}:${package}@${version}`
|
|
123
|
+
* @returns \{ name: `${registry}:${package}@${version}` } for deno
|
|
68
124
|
*/
|
|
69
|
-
export const
|
|
70
|
-
|
|
71
|
-
>({ packageManager: pm, dependencies }: T): string[] =>
|
|
125
|
+
export const joinDepsReg = (pm: PackageManager) => //
|
|
126
|
+
(dependencies: Deps): Deps =>
|
|
72
127
|
pipe(
|
|
73
128
|
dependencies,
|
|
74
129
|
entries,
|
|
75
|
-
map(([name, version]) =>
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
130
|
+
map(([name, version]): [string, string] => [
|
|
131
|
+
name.substring(4),
|
|
132
|
+
`${name}@${getPackageVersion(pm, version)}`,
|
|
133
|
+
]),
|
|
134
|
+
fromEntries,
|
|
79
135
|
);
|
|
80
136
|
|
|
81
|
-
const getPackageName = (pm: PackageManager, name: string) =>
|
|
82
|
-
pm !== "deno"
|
|
83
|
-
? name
|
|
84
|
-
: name.startsWith("npm:")
|
|
85
|
-
? name.substring(4)
|
|
86
|
-
: !name.startsWith("npm:")
|
|
87
|
-
? `jsr:${name}`
|
|
88
|
-
: name;
|
|
89
|
-
|
|
90
137
|
const getPackageVersion = (pm: PackageManager, version: string) =>
|
|
91
138
|
pm !== "deno" && version.includes("+")
|
|
92
139
|
? version.substring(0, version.indexOf("+"))
|
|
93
140
|
: version;
|
|
141
|
+
|
|
142
|
+
const normalizePackageNames = (pm: PackageManager) => (deps: Deps): Deps =>
|
|
143
|
+
pipe(
|
|
144
|
+
deps,
|
|
145
|
+
entries,
|
|
146
|
+
map(([name, version]): [string, string] => [
|
|
147
|
+
getPackageName(pm, name),
|
|
148
|
+
version,
|
|
149
|
+
]),
|
|
150
|
+
fromEntries,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
const getPackageName = (pm: PackageManager, name: string) =>
|
|
154
|
+
pm !== "deno"
|
|
155
|
+
? name.startsWith("npm:")
|
|
156
|
+
? name.replace("npm:", "") // not deno, have npm: prefix, remove it
|
|
157
|
+
: name // not deno, no prefix, keep it
|
|
158
|
+
: name.startsWith("npm:")
|
|
159
|
+
? name // deno, have npm: prefix, keep it
|
|
160
|
+
: `jsr:${name}` // deno, no prefix, add jsr: prefix
|
|
161
|
+
;
|
|
@@ -1,59 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { apply, pipe } from "@fxts/core";
|
|
2
|
+
import { CommandError, runSubCommand } from "../../utils.ts";
|
|
3
3
|
import type { InitCommandData } from "../types.ts";
|
|
4
|
-
import {
|
|
5
|
-
getAddDepsArgs,
|
|
6
|
-
getDependencies,
|
|
7
|
-
getDevDependencies,
|
|
8
|
-
joinDepsVer,
|
|
9
|
-
} from "./deps.ts";
|
|
10
|
-
import { noticeErrorWhileAddDeps } from "./notice.ts";
|
|
11
|
-
import { isDeno } from "./utils.ts";
|
|
12
4
|
|
|
13
5
|
const installDependencies = (data: InitCommandData) =>
|
|
14
6
|
pipe(
|
|
15
7
|
data,
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
({ packageManager, dir }) =>
|
|
9
|
+
[[packageManager, "install"], { cwd: dir }] as //
|
|
10
|
+
Parameters<typeof runSubCommand>,
|
|
11
|
+
apply(runSubCommand),
|
|
12
|
+
).catch((e) => {
|
|
13
|
+
if (e instanceof CommandError) {
|
|
14
|
+
console.error(
|
|
15
|
+
`Failed to install dependencies using ${data.packageManager}.`,
|
|
16
|
+
);
|
|
17
|
+
console.error("Command:", e.commandLine);
|
|
18
|
+
if (e.stderr) console.error("Error:", e.stderr);
|
|
19
|
+
throw e;
|
|
20
|
+
}
|
|
21
|
+
throw e;
|
|
22
|
+
});
|
|
19
23
|
|
|
20
24
|
export default installDependencies;
|
|
21
|
-
|
|
22
|
-
type Deps = Record<string, string>;
|
|
23
|
-
|
|
24
|
-
const installDeps = (data: InitCommandData) =>
|
|
25
|
-
pipe(
|
|
26
|
-
data,
|
|
27
|
-
set("dependencies", getDependencies),
|
|
28
|
-
getAddDepsCommand,
|
|
29
|
-
when(notEmpty, runAddDeps(data)),
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
const installDevDeps = (data: InitCommandData) =>
|
|
33
|
-
pipe(
|
|
34
|
-
data,
|
|
35
|
-
set("dependencies", getDevDependencies),
|
|
36
|
-
set("dev", always(true)),
|
|
37
|
-
getAddDepsCommand,
|
|
38
|
-
when(notEmpty, runAddDeps(data)),
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
const getAddDepsCommand = <
|
|
42
|
-
T extends InitCommandData & {
|
|
43
|
-
dependencies: Deps;
|
|
44
|
-
dev?: boolean;
|
|
45
|
-
},
|
|
46
|
-
>(data: T) =>
|
|
47
|
-
pipe(
|
|
48
|
-
data,
|
|
49
|
-
joinDepsVer,
|
|
50
|
-
when(notEmpty<string[]>, concat(getAddDepsArgs(data))),
|
|
51
|
-
toArray,
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
const runAddDeps =
|
|
55
|
-
<T extends { dir: string }>({ dir }: T) => (command: string[]) =>
|
|
56
|
-
runSubCommand(command, {
|
|
57
|
-
cwd: dir,
|
|
58
|
-
stdio: "inherit",
|
|
59
|
-
}).catch(noticeErrorWhileAddDeps(command));
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { print, printError } from "@optique/run";
|
|
1
|
+
import { text } from "@optique/core";
|
|
3
2
|
import { flow } from "es-toolkit";
|
|
4
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
colors,
|
|
5
|
+
printErrorMessage,
|
|
6
|
+
printMessage,
|
|
7
|
+
type RequiredNotNull,
|
|
8
|
+
} from "../../utils.ts";
|
|
5
9
|
import type { InitCommand } from "../command.ts";
|
|
6
10
|
import type { InitCommandData } from "../types.ts";
|
|
7
11
|
|
|
8
|
-
type PrintMessage = (...args: Parameters<typeof message>) => void;
|
|
9
|
-
const printMessage: PrintMessage = flow(message, print);
|
|
10
|
-
const printErrorMessage: PrintMessage = flow(message, printError);
|
|
11
|
-
|
|
12
12
|
export function drawDinosaur() {
|
|
13
13
|
const d = flow(colors.bgBlue, colors.black);
|
|
14
14
|
const f = colors.blue;
|
|
@@ -80,16 +80,18 @@ 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` ${key}
|
|
83
|
+
export const noticeEnvKeyValue = ([key, value]: [string, string]) => {
|
|
84
|
+
printMessage`${text(` ${key}='${value}'`)}`;
|
|
85
|
+
};
|
|
85
86
|
|
|
86
|
-
export
|
|
87
|
+
export const noticeHowToRun = (
|
|
87
88
|
{ initializer: { instruction, federationFile } }: InitCommandData,
|
|
88
|
-
)
|
|
89
|
-
printMessage
|
|
90
|
-
|
|
89
|
+
) =>
|
|
90
|
+
printMessage`
|
|
91
|
+
${instruction}
|
|
92
|
+
|
|
93
|
+
Start by editing the ${text(federationFile)} file to define your federation!
|
|
91
94
|
`;
|
|
92
|
-
}
|
|
93
95
|
|
|
94
96
|
export function noticeErrorWhileAddDeps(command: string[]) {
|
|
95
97
|
return (error: unknown) => {
|