@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
@@ -1,161 +0,0 @@
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";
12
- import { PACKAGE_VERSION } from "../lib.ts";
13
- import type { InitCommandData, PackageManager } from "../types.ts";
14
- import { PACKAGES_PATH } from "./const.ts";
15
- import { isDeno } from "./utils.ts";
16
-
17
- type Deps = Record<string, string>;
18
-
19
- /**
20
- * Gathers all dependencies required for the project based on the initializer,
21
- * key-value store, and message queue configurations.
22
- *
23
- * @param data - Web Framework initializer, key-value store and
24
- * message queue descriptions
25
- * @returns A record of dependencies with their versions
26
- */
27
- export const getDependencies = (
28
- { initializer, kv, mq, testMode, packageManager }: Pick<
29
- InitCommandData,
30
- "initializer" | "kv" | "mq" | "packageManager" | "testMode"
31
- >,
32
- ): Deps =>
33
- pipe(
34
- {
35
- "@fedify/fedify": PACKAGE_VERSION,
36
- "@logtape/logtape": "^1.1.0",
37
- },
38
- merge(initializer.dependencies),
39
- merge(kv.dependencies),
40
- merge(mq.dependencies),
41
- when(
42
- always(testMode),
43
- isDeno({ packageManager }) ? removeFedifyDeps : addLocalFedifyDeps,
44
- ),
45
- normalizePackageNames(packageManager),
46
- );
47
-
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.
79
- *
80
- * @param data - Web Framework initializer, key-value store
81
- * and message queue descriptions
82
- * @returns A record of devDependencies with their versions
83
- */
84
- export const getDevDependencies = (
85
- { initializer, kv, mq, packageManager }: Pick<
86
- InitCommandData,
87
- "initializer" | "kv" | "mq" | "packageManager"
88
- >,
89
- ): Deps =>
90
- pipe(
91
- {
92
- "@biomejs/biome": "^2.2.4",
93
- },
94
- merge(initializer.devDependencies),
95
- merge(kv.devDependencies),
96
- merge(mq.devDependencies),
97
- normalizePackageNames(packageManager),
98
- );
99
-
100
- /**
101
- * Generates the command-line arguments needed to add dependencies
102
- * or devDependencies using the specified package manager.
103
- * If it is devDependencies, the '-D' flag is included.
104
- *
105
- * @param param0 - Object containing the package manager and a boolean
106
- * indicating if dev dependencies are to be added
107
- * @yields The command-line arguments as strings
108
- */
109
- export function* getAddDepsArgs<
110
- T extends { packageManager: PackageManager; dev?: boolean },
111
- >({ packageManager, dev = false }: T): Generator<string> {
112
- yield packageManager;
113
- yield "add";
114
- if (dev) yield "-D";
115
- }
116
-
117
- /**
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:'.
121
- *
122
- * @param data - Package manager and dependencies to be joined with versions
123
- * @returns \{ name: `${registry}:${package}@${version}` } for deno
124
- */
125
- export const joinDepsReg = (pm: PackageManager) => //
126
- (dependencies: Deps): Deps =>
127
- pipe(
128
- dependencies,
129
- entries,
130
- map(([name, version]): [string, string] => [
131
- name.substring(4),
132
- `${name}@${getPackageVersion(pm, version)}`,
133
- ]),
134
- fromEntries,
135
- );
136
-
137
- const getPackageVersion = (pm: PackageManager, version: string) =>
138
- pm !== "deno" && version.includes("+")
139
- ? version.substring(0, version.indexOf("+"))
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,11 +0,0 @@
1
- import { mkdir } from "node:fs/promises";
2
- import type { InitCommandData } from "../types.ts";
3
-
4
- /**
5
- * Creates the target directory if it does not exist.
6
- *
7
- * @param data - The directory
8
- * @returns A promise that resolves when the directory is created
9
- */
10
- export const makeDirIfHyd = ({ dir }: InitCommandData): //
11
- Promise<string | undefined> => mkdir(dir, { recursive: true });
@@ -1,14 +0,0 @@
1
- import { entries, forEach, pipeLazy, tap, toArray, when } from "@fxts/core";
2
- import { notEmpty } from "../../utils.ts";
3
- import type { InitCommandIo } from "../types.ts";
4
- import { noticeConfigEnv, noticeEnvKeyValue } from "./notice.ts";
5
-
6
- const recommendConfigEnv: InitCommandIo = pipeLazy(
7
- (data) => data.env,
8
- entries,
9
- toArray<Iterable<[string, string]>>,
10
- when(notEmpty, tap<[string, string][], void>(noticeConfigEnv)),
11
- forEach(noticeEnvKeyValue),
12
- );
13
-
14
- export default recommendConfigEnv;
@@ -1,24 +0,0 @@
1
- import { apply, pipe } from "@fxts/core";
2
- import { CommandError, runSubCommand } from "../../utils.ts";
3
- import type { InitCommandData } from "../types.ts";
4
-
5
- const installDependencies = (data: InitCommandData) =>
6
- pipe(
7
- data,
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
- });
23
-
24
- export default installDependencies;
@@ -1,66 +0,0 @@
1
- import { pipe, tap, unless, when } from "@fxts/core";
2
- import askOptions from "../ask/mod.ts";
3
- import type { InitCommand } from "../command.ts";
4
- import type { InitCommandData } from "../types.ts";
5
- import { makeDirIfHyd } from "./dir.ts";
6
- import recommendConfigEnv from "./env.ts";
7
- import installDependencies from "./install.ts";
8
- import {
9
- drawDinosaur,
10
- noticeHowToRun,
11
- noticeOptions,
12
- noticePrecommand,
13
- } from "./notice.ts";
14
- import { patchFiles, recommendPatchFiles } from "./patch.ts";
15
- import runPrecommand from "./precommand.ts";
16
- import recommendDependencies from "./recommend.ts";
17
- import setData from "./set.ts";
18
- import { hasCommand, isDry } from "./utils.ts";
19
-
20
- /**
21
- * options: InitCommand
22
- * ├ drawDinosaur
23
- * ┌─────┴──────┐
24
- * │ askOptions │ InitCommand -> InitCommandOptions
25
- * └─────┬──────┘
26
- * ├ noticeOptions
27
- * ┌────┴────┐
28
- * │ setData │ InitCommandOptions -> InitCommandData
29
- * └────┬────┘
30
- * ┌─┴─┐ isDry
31
- * handleDryRun ┤ ├ handleHydRun
32
- * └─┬─┘
33
- * ├ recommendConfigEnv
34
- * ├ noticeHowToRun
35
- */
36
- const runInit = (options: InitCommand) =>
37
- pipe(
38
- options,
39
- tap(drawDinosaur),
40
- askOptions,
41
- tap(noticeOptions),
42
- setData,
43
- when(isDry, handleDryRun),
44
- unless(isDry, handleHydRun),
45
- tap(recommendConfigEnv),
46
- tap(noticeHowToRun),
47
- );
48
-
49
- export default runInit;
50
-
51
- const handleDryRun = (data: InitCommandData) =>
52
- pipe(
53
- data,
54
- tap(when(hasCommand, noticePrecommand)),
55
- tap(recommendPatchFiles),
56
- tap(recommendDependencies),
57
- );
58
-
59
- const handleHydRun = (data: InitCommandData) =>
60
- pipe(
61
- data,
62
- tap(makeDirIfHyd),
63
- tap(when(hasCommand, runPrecommand)),
64
- tap(patchFiles),
65
- tap(installDependencies),
66
- );
@@ -1,103 +0,0 @@
1
- import { text } from "@optique/core";
2
- import { flow } from "es-toolkit";
3
- import {
4
- colors,
5
- printErrorMessage,
6
- printMessage,
7
- type RequiredNotNull,
8
- } from "../../utils.ts";
9
- import type { InitCommand } from "../command.ts";
10
- import type { InitCommandData } from "../types.ts";
11
-
12
- export function drawDinosaur() {
13
- const d = flow(colors.bgBlue, colors.black);
14
- const f = colors.blue;
15
- console.error(`\
16
- ${d(" ___ ")} ${f(" _____ _ _ __")}
17
- ${d(" /'_') ")} ${f("| ___|__ __| (_)/ _|_ _")}
18
- ${d(" .-^^^-/ / ")} ${f("| |_ / _ \\/ _` | | |_| | | |")}
19
- ${d(" __/ / ")} ${f("| _| __/ (_| | | _| |_| |")}
20
- ${d(" <__.|_|-|_| ")} ${f("|_| \\___|\\__,_|_|_| \\__, |")}
21
- ${d(" ")} ${f(" |___/")}
22
- `);
23
- }
24
-
25
- export const noticeOptions: (options: RequiredNotNull<InitCommand>) => void = (
26
- {
27
- packageManager,
28
- webFramework,
29
- kvStore,
30
- messageQueue,
31
- },
32
- ) =>
33
- printMessage`
34
- Package manager: ${packageManager};
35
- Web framework: ${webFramework};
36
- Key–value store: ${kvStore};
37
- Message queue: ${messageQueue};
38
- `;
39
-
40
- export const noticeDry = () =>
41
- printMessage`🔍 DRY RUN MODE - No files will be created\n`;
42
-
43
- export function noticePrecommand({
44
- initializer: { command },
45
- dir,
46
- }: InitCommandData) {
47
- printMessage`📦 Would run command:`;
48
- printMessage` cd ${dir}`;
49
- printMessage` ${command!.join(" ")}\n`;
50
- }
51
-
52
- export const noticeFilesToCreate = () =>
53
- //
54
- printMessage`📄 Would create files:\n`;
55
-
56
- export const noticeFilesToInsert = () =>
57
- printMessage`Would create/update JSON files:\n`;
58
-
59
- export const noticeDepsIfExist = () =>
60
- printMessage`📦 Would install dependencies:`;
61
-
62
- export const noticeDevDepsIfExist = () =>
63
- printMessage`📦 Would install dev dependencies:`;
64
-
65
- export const noticeDeps = ([name, version]: [string, string]) =>
66
- printMessage`${name}@${version}`;
67
-
68
- export function displayFile(
69
- path: string,
70
- content: string,
71
- emoji: string = "📄",
72
- ) {
73
- printMessage`${emoji} ${path}`;
74
- printMessage`${"─".repeat(60)}`;
75
- printMessage`${content}`;
76
- printMessage`${"─".repeat(60)}\n`;
77
- }
78
-
79
- export const noticeConfigEnv = () =>
80
- printMessage`Note that you probably want to edit the ${".env"} file.
81
- It currently contains the following values:\n`;
82
-
83
- export const noticeEnvKeyValue = ([key, value]: [string, string]) => {
84
- printMessage`${text(` ${key}='${value}'`)}`;
85
- };
86
-
87
- export const noticeHowToRun = (
88
- { initializer: { instruction, federationFile } }: InitCommandData,
89
- ) =>
90
- printMessage`
91
- ${instruction}
92
-
93
- Start by editing the ${text(federationFile)} file to define your federation!
94
- `;
95
-
96
- export function noticeErrorWhileAddDeps(command: string[]) {
97
- return (error: unknown) => {
98
- printErrorMessage`The command ${command.join(" ")} failed with the error: ${
99
- String(error)
100
- }`;
101
- throw new Error("Failed to add dependencies.");
102
- };
103
- }
@@ -1,233 +0,0 @@
1
- import { always, apply, entries, map, pipe, pipeLazy, tap } from "@fxts/core";
2
- import { toMerged } from "es-toolkit";
3
- import { readFile } from "node:fs/promises";
4
- import { formatJson, merge, replaceAll, set } from "../../utils.ts";
5
- import { createFile, throwUnlessNotExists } from "../lib.ts";
6
- import type { InitCommandData } from "../types.ts";
7
- import {
8
- devToolConfigs,
9
- loadDenoConfig,
10
- loadPackageJson,
11
- loadTsConfig,
12
- } from "./configs.ts";
13
- import {
14
- displayFile,
15
- noticeFilesToCreate,
16
- noticeFilesToInsert,
17
- } from "./notice.ts";
18
- import { getImports, loadFederation, loadLogging } from "./templates.ts";
19
- import { joinDir, stringifyEnvs } from "./utils.ts";
20
-
21
- /**
22
- * Main function that initializes the project by creating necessary files and configurations.
23
- * Handles both dry-run mode (recommending files) and actual file creation.
24
- * Orchestrates the entire file generation and writing process.
25
- *
26
- * @param data - The initialization command data containing project
27
- * configuration
28
- * @returns A processed data object with files and JSONs ready for creation
29
- */
30
- export const patchFiles = (data: InitCommandData) =>
31
- pipe(
32
- data,
33
- set("files", getFiles),
34
- set("jsons", getJsons),
35
- createFiles,
36
- );
37
-
38
- export const recommendPatchFiles = (data: InitCommandData) =>
39
- pipe(
40
- data,
41
- set("files", getFiles),
42
- set("jsons", getJsons),
43
- recommendFiles,
44
- );
45
-
46
- /**
47
- * Generates text-based files (TypeScript, environment files) for the project.
48
- * Creates federation configuration, logging setup, environment variables, and
49
- * framework-specific files by processing templates and combining them with
50
- * project-specific data.
51
- *
52
- * @param data - The initialization command data
53
- * @returns A record of file paths to their string content
54
- */
55
- const getFiles = <
56
- T extends InitCommandData,
57
- >(data: T) => ({
58
- [data.initializer.federationFile]: loadFederation({
59
- imports: getImports(data),
60
- ...data,
61
- }),
62
- [data.initializer.loggingFile]: loadLogging(data),
63
- ".env": stringifyEnvs(data.env),
64
- ...data.initializer.files,
65
- });
66
-
67
- /**
68
- * Generates JSON configuration files based on the package manager type.
69
- * Creates different sets of configuration files for Deno vs other environments,
70
- * including compiler configs, package manifests, and development
71
- * tool configurations.
72
- *
73
- * @param data - The initialization command data
74
- * @returns A record of file paths to their JSON object content
75
- */
76
- const getJsons = <
77
- T extends InitCommandData,
78
- >(data: T): Record<string, object> =>
79
- data.packageManager === "deno"
80
- ? {
81
- "deno.json": loadDenoConfig(data).data,
82
- [devToolConfigs["vscSetDeno"].path]: devToolConfigs["vscSetDeno"].data,
83
- [devToolConfigs["vscExtDeno"].path]: devToolConfigs["vscExtDeno"].data,
84
- }
85
- : {
86
- ...(data.initializer.compilerOptions
87
- ? { "tsconfig.json": loadTsConfig(data).data }
88
- : {}),
89
- "package.json": loadPackageJson(data).data,
90
- [devToolConfigs["biome"].path]: devToolConfigs["biome"].data,
91
- [devToolConfigs["vscSet"].path]: devToolConfigs["vscSet"].data,
92
- [devToolConfigs["vscExt"].path]: devToolConfigs["vscExt"].data,
93
- };
94
-
95
- /**
96
- * Handles dry-run mode by recommending files to be created without actually
97
- * creating them.
98
- * Displays what files would be created and shows their content for user review,
99
- * so users can preview the initialization process before committing to it.
100
- *
101
- * @param data - The initialization command data with files and JSONs prepared
102
- * @returns The processed data with recommendations displayed
103
- */
104
- const recommendFiles = (data: InitCommandWithFiles) =>
105
- pipe(
106
- data,
107
- tap(noticeFilesToCreate),
108
- tap(processAllFiles(displayFile)),
109
- tap(noticeFilesToInsert),
110
- set("files", ({ jsons }) => jsons),
111
- tap(processAllFiles(displayFile)),
112
- );
113
-
114
- /**
115
- * Actually creates files on the filesystem during normal execution.
116
- * Merges text files and JSON files together and writes them to disk.
117
- * This performs the actual file system operations to initialize the project.
118
- *
119
- * @param data - The initialization command data with files and JSONs prepared
120
- * @returns The processed data after files have been created
121
- */
122
- const createFiles = (data: InitCommandWithFiles) =>
123
- pipe(
124
- data,
125
- set("files", ({ jsons, files }) => toMerged(files, jsons)),
126
- tap(processAllFiles(createFile)),
127
- );
128
-
129
- interface InitCommandWithFiles extends InitCommandData {
130
- files: Record<string, string>;
131
- jsons: Record<string, object>;
132
- }
133
-
134
- /**
135
- * Processes all files with a given processing function.
136
- * Takes a processor (either display or create) and applies it to all files
137
- * in the target directory, handling path resolution and content patching.
138
- *
139
- * @param process - Function to process each file (either display or create)
140
- * @returns A function that processes all files in the given directory with the provided processor
141
- */
142
- const processAllFiles = (
143
- process: (path: string, content: string) => void | Promise<void>,
144
- ) =>
145
- ({ dir, files }: InitCommandWithFiles) =>
146
- pipe(
147
- files,
148
- entries,
149
- map(
150
- pipeLazy(
151
- joinDir(dir),
152
- apply(patchContent),
153
- apply(process),
154
- ),
155
- ),
156
- Array.fromAsync,
157
- );
158
-
159
- /**
160
- * Patches file content by either merging JSON or appending text content.
161
- * Handles existing files by reading their current content and intelligently
162
- * combining it with new content based on the content type (JSON vs text).
163
- *
164
- * @param path - The file path to patch
165
- * @param content - The new content (either string or object)
166
- * @returns A tuple containing the file path and the final content string
167
- */
168
- async function patchContent(
169
- path: string,
170
- content: string | object,
171
- ): Promise<[string, string]> {
172
- const prev = await readFileIfExists(path);
173
- const data = typeof content === "object"
174
- ? mergeJson(prev, content)
175
- : appendText(prev, content);
176
- return [path, data];
177
- }
178
-
179
- /**
180
- * Merges new JSON data with existing JSON content and formats the result.
181
- * Parses existing JSON content (if any) and deep merges it with new data,
182
- * then formats the result for consistent output.
183
- * Supports JSONC (JSON with Comments) by removing comments before parsing.
184
- *
185
- * @param prev - The previous JSON content as string
186
- * @param data - The new data object to merge
187
- * @returns Formatted JSON string with merged content
188
- */
189
- const mergeJson = (prev: string, data: object): string =>
190
- pipe(
191
- prev ? JSON.parse(removeJsonComments(prev)) : {},
192
- merge(data),
193
- formatJson,
194
- );
195
-
196
- /**
197
- * Removes single-line (//) and multi-line (/* *\/) comments from JSON string.
198
- * This allows parsing JSONC (JSON with Comments) files.
199
- *
200
- * @param jsonString - The JSON string potentially containing comments
201
- * @returns JSON string with comments removed
202
- */
203
- const removeJsonComments = (jsonString: string): string =>
204
- pipe(
205
- jsonString,
206
- replaceAll(/\/\/.*$/gm, ""),
207
- replaceAll(/\/\*[\s\S]*?\*\//g, ""),
208
- );
209
-
210
- /**
211
- * Appends new text content to existing text content line by line.
212
- * Concatenates new content lines with existing content lines,
213
- * preserving line structure and formatting.
214
- *
215
- * @param prev - The previous text content
216
- * @param data - The new text content to append
217
- * @returns Combined text content as a single string
218
- */
219
- const appendText = (prev: string, data: string) =>
220
- prev ? `${prev}\n${data}` : data;
221
-
222
- /**
223
- * Safely reads a file if it exists, returns empty string if it doesn't exist.
224
- * Provides error handling to distinguish between "file not found" and other
225
- * file system errors, throwing only for unexpected errors.
226
- *
227
- * @param path - The file path to read
228
- * @returns The file content as string, or empty string if file doesn't exist
229
- * @throws Error if file access fails for reasons other than file not existing
230
- */
231
- const readFileIfExists = (path: string): Promise<string> =>
232
- readFile(path, "utf8")
233
- .catch(pipeLazy(tap(throwUnlessNotExists), always("")));
@@ -1,29 +0,0 @@
1
- import { CommandError, exit, runSubCommand } from "../../utils.ts";
2
- import type { InitCommandData } from "../types.ts";
3
-
4
- /**
5
- * Runs the precommand specified in the initializer to set up the project.
6
- *
7
- * @param data - The initialization command data containing the initializer command and directory
8
- * @returns A promise that resolves when the precommand has been executed
9
- */
10
- const runPrecommand = ({
11
- initializer: { command },
12
- dir,
13
- }: InitCommandData) =>
14
- runSubCommand(command!, {
15
- cwd: dir,
16
- stdio: "inherit",
17
- }).catch((e) => {
18
- if (e instanceof CommandError) {
19
- console.error("Failed to run the precommand.");
20
- console.error("Command:", e.commandLine);
21
- if (e.stderr) console.error("Error:", e.stderr);
22
- if (e.stdout) console.error("Output:", e.stdout);
23
- } else {
24
- console.error("Failed to run the precommand:", e);
25
- }
26
- exit(1);
27
- });
28
-
29
- export default runPrecommand;
@@ -1,38 +0,0 @@
1
- import { map, peek, pipeLazy, tap, unless, when } from "@fxts/core";
2
- import { notEmpty } from "../../utils.ts";
3
- import type { InitCommandIo } from "../types.ts";
4
- import { getDependencies, getDevDependencies } from "./deps.ts";
5
- import {
6
- noticeDeps,
7
- noticeDepsIfExist,
8
- noticeDevDepsIfExist,
9
- } from "./notice.ts";
10
- import { isDeno } from "./utils.ts";
11
-
12
- const recommendDeps: InitCommandIo = pipeLazy(
13
- getDependencies,
14
- Object.entries<string>,
15
- when(notEmpty<[string, string][]>, tap(noticeDepsIfExist)),
16
- peek(noticeDeps),
17
- );
18
-
19
- const recommendDevDeps: InitCommandIo = pipeLazy(
20
- getDevDependencies,
21
- Object.entries<string>,
22
- when(notEmpty<[string, string][]>, tap(noticeDevDepsIfExist)),
23
- map(noticeDeps),
24
- );
25
-
26
- /**
27
- * Recommends dependencies and devDependencies to be added to package.json.
28
- * Skips devDependencies recommendation if the package manager is Deno.
29
- *
30
- * @param data - The initialization command data
31
- * @returns An InitCommandIo function that performs the recommendation
32
- */
33
- const recommendDependencies: InitCommandIo = pipeLazy(
34
- tap(recommendDeps),
35
- unless(isDeno, tap(recommendDevDeps)),
36
- );
37
-
38
- export default recommendDependencies;