@fedify/init 2.4.0-dev.1666 → 2.4.0-dev.1727

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/README.md CHANGED
@@ -25,17 +25,20 @@ Supported options
25
25
 
26
26
  The initializer supports the following project configurations:
27
27
 
28
- - **Web frameworks**: Bare-bones, [Hono], [Nitro], [Next.js], [Elysia],
29
- [Express]
28
+ - **Web frameworks**: Bare-bones, [Astro], [Elysia], [Express], [Hono],
29
+ [Next.js], [Nitro], [Nuxt], [SolidStart]
30
30
  - **Package managers**: Deno, pnpm, Bun, Yarn, npm
31
31
  - **Key-value stores**: In-Memory, Deno KV, Redis, PostgreSQL
32
32
  - **Message queues**: In-Process, Deno KV, Redis, PostgreSQL, AMQP
33
33
 
34
- [Hono]: https://hono.dev/
35
- [Nitro]: https://nitro.build/
36
- [Next.js]: https://nextjs.org/
34
+ [Astro]: https://astro.build/
37
35
  [Elysia]: https://elysiajs.com/
38
36
  [Express]: https://expressjs.com/
37
+ [Hono]: https://hono.dev/
38
+ [Next.js]: https://nextjs.org/
39
+ [Nitro]: https://nitro.build/
40
+ [Nuxt]: https://nuxt.com/
41
+ [SolidStart]: https://start.solidjs.com/
39
42
 
40
43
 
41
44
  Installation
@@ -66,7 +66,10 @@ const getDenoVersionFromCommand = () => {
66
66
  const getDenoVersionFromRuntime = () => pipe(globalThis, prop("Deno"), prop("version"), prop("deno"));
67
67
  const parseVersion = (deno) => pipe(deno.match(/^(\d+)\.(\d+)\.(\d+)/), unless(isNull, ([, ...segments]) => segments.map(Number)));
68
68
  const isLaterOrEqualThan = (basis) => (target) => pipe(zip(basis, target), filter(([b, t]) => t !== b), head, (a) => a ? a[0] < a[1] : true);
69
- const getLinks = ({ kv, mq, initializer, dir }) => pipe({ "@fedify/fedify": "" }, merge(initializer.dependencies), merge(kv.dependencies), merge(mq.dependencies), keys, filter((dep) => dep.includes("@fedify/")), map((dep) => dep.replace("@fedify/", "")), map((dep) => join(getPackagesPath(), dep)), map(realpathSync), map((realAbsolutePath) => relative(realpathSync(dir), realAbsolutePath)), toArray);
69
+ const getLinks = ({ kv, mq, initializer, dir }) => pipe({
70
+ "@fedify/fedify": "",
71
+ "@fedify/vocab": ""
72
+ }, merge(initializer.dependencies), merge(kv.dependencies), merge(mq.dependencies), keys, filter((dep) => dep.includes("@fedify/")), map((dep) => dep.replace("@fedify/", "")), map((dep) => join(getPackagesPath(), dep)), map(realpathSync), map((realAbsolutePath) => relative(realpathSync(dir), realAbsolutePath)), toArray);
70
73
  /**
71
74
  * Loads TypeScript configuration object for Node.js/Bun projects.
72
75
  * Uses compiler options from the framework initializer.
@@ -116,7 +119,7 @@ const loadVscodeExtensions = (data) => ({
116
119
  });
117
120
  const withFormatIgnorePatterns = (config, data) => ({
118
121
  ...config,
119
- ignorePatterns: [...new Set([...config.ignorePatterns ?? [], ...data.initializer.format?.ignorePatterns ?? []])].sort()
122
+ ignorePatterns: [.../* @__PURE__ */ new Set([...config.ignorePatterns ?? [], ...data.initializer.format?.ignorePatterns ?? []])].sort()
120
123
  });
121
124
  function getVscodeSettingsForPrettier() {
122
125
  const { "oxc.fmt.configPath": _configPath, ...settings } = vscode_settings_default;
@@ -1,6 +1,6 @@
1
1
  import { merge, replace } from "../utils.js";
2
2
  import { PACKAGE_VERSION } from "../lib.js";
3
- import { _logtape_logtape, _std_dotenv } from "../json/deps.js";
3
+ import { "@logtape/logtape" as _logtape_logtape, "@std/dotenv" as _std_dotenv } from "../json/deps.js";
4
4
  import { getPackagesPath } from "./const.js";
5
5
  import { isDeno, needsDenoDotenv } from "./utils.js";
6
6
  import { always, entries, filter, fromEntries, map, pipe, when } from "@fxts/core";
@@ -14,7 +14,7 @@ import { join as join$1 } from "node:path";
14
14
  * message queue descriptions
15
15
  * @returns A record of dependencies with their versions
16
16
  */
17
- const getDependencies = ({ initializer, kv, mq, env, testMode, packageManager }) => pipe({
17
+ const getDependencies = ({ initializer, kv, mq, env, testMode, packageManager, webFramework }) => pipe({
18
18
  "@fedify/fedify": PACKAGE_VERSION,
19
19
  "@fedify/vocab": PACKAGE_VERSION,
20
20
  "@logtape/logtape": _logtape_logtape,
@@ -22,7 +22,8 @@ const getDependencies = ({ initializer, kv, mq, env, testMode, packageManager })
22
22
  packageManager,
23
23
  env
24
24
  }) && { "@std/dotenv": _std_dotenv }
25
- }, merge(initializer.dependencies), merge(kv.dependencies), merge(mq.dependencies), when(always(testMode), isDeno({ packageManager }) ? removeFedifyDeps : addLocalFedifyDeps), normalizePackageNames(packageManager));
25
+ }, merge(initializer.dependencies), merge(kv.dependencies), merge(mq.dependencies), when(always(packageManager === "deno" && webFramework === "astro"), useNpmForFedifyPackages), when(always(testMode), isDeno({ packageManager }) ? removeFedifyDeps : addLocalFedifyDeps), normalizePackageNames(packageManager));
26
+ const useNpmForFedifyPackages = (deps) => pipe(deps, entries, map(([name, version]) => name.startsWith("@fedify/") && name !== "@fedify/lint" && !version.startsWith("npm:") ? [name, `npm:${name}@${version}`] : [name, version]), fromEntries);
26
27
  const removeFedifyDeps = (deps) => pipe(deps, entries, filter(([name]) => !name.includes("@fedify")), fromEntries);
27
28
  const addLocalFedifyDeps = (deps) => pipe(deps, entries, map(when(([name]) => name.includes("@fedify/"), ([name, _version]) => [name, convertFedifyToLocal(name)])), fromEntries);
28
29
  const convertFedifyToLocal = (name) => pipe(name, replace("@fedify/", ""), (pkg) => join$1(getPackagesPath(), pkg));
@@ -21,4 +21,4 @@ import { InitCommandData } from "../types.js";
21
21
  */
22
22
  declare const runInit: (options: InitCommand) => Promise<InitCommandData>;
23
23
  //#endregion
24
- export { runInit };
24
+ export { runInit as default };
@@ -233,4 +233,4 @@ const appendText = (prev, data) => prev ? `${prev}\n${data}` : data;
233
233
  */
234
234
  const readFileIfExists = (path) => readFile(path, "utf8").catch(pipeLazy(tap(throwUnlessNotExists), always("")));
235
235
  //#endregion
236
- export { assertNoGeneratedFileConflicts, patchFiles, recommendPatchFiles };
236
+ export { GeneratedFileConflictError, assertNoGeneratedFileConflicts, getJsonsCacheKey, patchFiles, recommendPatchFiles };
@@ -75,4 +75,4 @@ const ENV_REG_EXP = /process\.env\.(\w+)/g;
75
75
  */
76
76
  const convertEnv = (obj, pm) => pm === "deno" && ENV_REG_EXP.test(obj) ? obj.replaceAll(ENV_REG_EXP, (_, g1) => `Deno.env.get("${g1}")`) : obj;
77
77
  //#endregion
78
- export { getImports, loadFederation, loadLogging };
78
+ export { convertEnv, getAlias, getImports, loadFederation, loadLogging };
@@ -1,4 +1,5 @@
1
1
  import $ from "@david/dax";
2
+ import { readFile, writeFile } from "node:fs/promises";
2
3
  import { join } from "node:path";
3
4
  //#region src/action/utils.ts
4
5
  /** Returns `true` if the current run is in dry-run mode. */
@@ -60,7 +61,21 @@ function stringifyEnvs(object) {
60
61
  * Runs `<packageManager> install` in the project directory to install all
61
62
  * dependencies. Logs an error message if the installation fails.
62
63
  */
63
- const installDependencies = ({ packageManager, dir }) => $`${packageManager} install`.cwd(dir).spawn();
64
+ const installDependencies = async (data) => {
65
+ const { packageManager, dir, testMode } = data;
66
+ if (packageManager !== "deno" || !testMode) return await $`${packageManager} install`.cwd(dir).spawn();
67
+ const configPath = join(dir, "deno.json");
68
+ const config = JSON.parse(await readFile(configPath, "utf8"));
69
+ const links = config.links;
70
+ delete config.links;
71
+ await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
72
+ try {
73
+ return await $`${packageManager} install`.cwd(dir).spawn();
74
+ } finally {
75
+ config.links = links;
76
+ await writeFile(configPath, JSON.stringify(config, null, 2) + "\n");
77
+ }
78
+ };
64
79
  /**
65
80
  * Runs the precommand specified in the initializer to set up the project.
66
81
  *
package/dist/deno.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region deno.json
2
- var version = "2.4.0-dev.1666+690d9b28";
2
+ var version = "2.4.0-dev.1727+1eadcb04";
3
3
  //#endregion
4
4
  export { version };
package/dist/json/deps.js CHANGED
@@ -3,12 +3,11 @@ var _hongminhee_x_forwarded_fetch = "^0.2.0";
3
3
  var _hono_hono = "^4.12.27";
4
4
  var _logtape_logtape = "^2.2.1";
5
5
  var _std_dotenv = "^0.225.7";
6
- var npm__astrojs_node = "^10.0.4";
7
- var npm__deno_astro_adapter = "^0.5.2";
6
+ var npm__astrojs_node = "^11.0.2";
7
+ var npm__deno_astro_adapter = "^0.6.0";
8
8
  var npm__dotenvx_dotenvx = "^1.75.1";
9
9
  var npm__elysiajs_node = "^1.4.5";
10
10
  var npm__hono_node_server = "^1.19.12";
11
- var npm__nurodev_astro_bun = "^2.1.2";
12
11
  var npm__sinclair_typebox = "^0.34.49";
13
12
  var npm__solidjs_router = "^0.16.1";
14
13
  var npm__solidjs_start = "^1.3.2";
@@ -17,6 +16,8 @@ var npm__types_express = "^4.17.21";
17
16
  var npm__types_node_20 = "^20.11.2";
18
17
  var npm__types_node_22 = "^22.17.0";
19
18
  var npm__types_node_25 = "^25.5.0";
19
+ var npm_astro = "^7.0.7";
20
+ var npm_create_astro = "^5.2.2";
20
21
  var npm_elysia = "^1.4.29";
21
22
  var npm_express = "^5.2.1";
22
23
  var npm_hono = "^4.12.27";
@@ -31,4 +32,4 @@ var npm_typescript = "^5.9.3";
31
32
  var npm_vinxi = "^0.5.11";
32
33
  var npm_x_forwarded_fetch = "^0.2.0";
33
34
  //#endregion
34
- export { _hongminhee_x_forwarded_fetch, _hono_hono, _logtape_logtape, _std_dotenv, npm__astrojs_node, npm__deno_astro_adapter, npm__dotenvx_dotenvx, npm__elysiajs_node, npm__hono_node_server, npm__nurodev_astro_bun, npm__sinclair_typebox, npm__solidjs_router, npm__solidjs_start, npm__types_bun, npm__types_express, npm__types_node_20, npm__types_node_22, npm__types_node_25, npm_elysia, npm_express, npm_hono, npm_openapi_types, npm_oxfmt, npm_oxlint, npm_prettier, npm_prettier_plugin_astro, npm_solid_js, npm_tsx, npm_typescript, npm_vinxi, npm_x_forwarded_fetch };
35
+ export { _hongminhee_x_forwarded_fetch as "@hongminhee/x-forwarded-fetch", _hono_hono as "@hono/hono", _logtape_logtape as "@logtape/logtape", _std_dotenv as "@std/dotenv", npm__astrojs_node as "npm:@astrojs/node", npm__deno_astro_adapter as "npm:@deno/astro-adapter", npm__dotenvx_dotenvx as "npm:@dotenvx/dotenvx", npm__elysiajs_node as "npm:@elysiajs/node", npm__hono_node_server as "npm:@hono/node-server", npm__sinclair_typebox as "npm:@sinclair/typebox", npm__solidjs_router as "npm:@solidjs/router", npm__solidjs_start as "npm:@solidjs/start", npm__types_bun as "npm:@types/bun", npm__types_express as "npm:@types/express", npm__types_node_20 as "npm:@types/node@20", npm__types_node_22 as "npm:@types/node@22", npm__types_node_25 as "npm:@types/node@25", npm_astro as "npm:astro", npm_create_astro as "npm:create-astro", npm_elysia as "npm:elysia", npm_express as "npm:express", npm_hono as "npm:hono", npm_openapi_types as "npm:openapi-types", npm_oxfmt as "npm:oxfmt", npm_oxlint as "npm:oxlint", npm_prettier as "npm:prettier", npm_prettier_plugin_astro as "npm:prettier-plugin-astro", npm_solid_js as "npm:solid-js", npm_tsx as "npm:tsx", npm_typescript as "npm:typescript", npm_vinxi as "npm:vinxi", npm_x_forwarded_fetch as "npm:x-forwarded-fetch" };
@@ -3,13 +3,12 @@
3
3
  "@hono/hono": "^4.12.27",
4
4
  "@logtape/logtape": "^2.2.1",
5
5
  "@std/dotenv": "^0.225.7",
6
- "npm:@astrojs/node": "^10.0.4",
7
- "npm:@deno/astro-adapter": "^0.5.2",
6
+ "npm:@astrojs/node": "^11.0.2",
7
+ "npm:@deno/astro-adapter": "^0.6.0",
8
8
  "npm:@dotenvx/dotenvx": "^1.75.1",
9
9
  "npm:@elysiajs/node": "^1.4.5",
10
10
  "npm:@hono/node-server": "^1.19.12",
11
11
  "npm:@nuxt/kit": "^4.4.8",
12
- "npm:@nurodev/astro-bun": "^2.1.2",
13
12
  "npm:@sinclair/typebox": "^0.34.49",
14
13
  "npm:@solidjs/router": "^0.16.1",
15
14
  "npm:@solidjs/start": "^1.3.2",
@@ -18,7 +17,8 @@
18
17
  "npm:@types/node@20": "^20.11.2",
19
18
  "npm:@types/node@22": "^22.17.0",
20
19
  "npm:@types/node@25": "^25.5.0",
21
- "npm:astro": "^6.1.1",
20
+ "npm:astro": "^7.0.7",
21
+ "npm:create-astro": "^5.2.2",
22
22
  "npm:elysia": "^1.4.29",
23
23
  "npm:express": "^5.2.1",
24
24
  "npm:h3": "^1.15.0",
package/dist/lib.js CHANGED
@@ -87,6 +87,20 @@ const readTemplate = async (templatePath) => {
87
87
  * package manager (e.g., `"deno task dev"`, `"bun dev"`, `"npm run dev"`).
88
88
  */
89
89
  const getDevCommand = (pm) => pm === "deno" ? "deno task dev" : pm === "bun" ? "bun dev" : `${pm} run dev`;
90
+ /** Returns the command to build for the given package manager. */
91
+ const getBuildCommand = (pm) => pm === "deno" ? [
92
+ "deno",
93
+ "task",
94
+ "build"
95
+ ] : pm === "bun" ? [
96
+ "bun",
97
+ "run",
98
+ "build"
99
+ ] : [
100
+ pm,
101
+ "run",
102
+ "build"
103
+ ];
90
104
  async function isCommandAvailable({ checkCommand, outputPattern }) {
91
105
  try {
92
106
  const { stdout } = await $`${checkCommand}`.stdout("piped").spawn();
@@ -277,4 +291,4 @@ const isDirectory = async (path) => {
277
291
  /** Returns `true` if the current run is in test mode. */
278
292
  const isTest = ({ testMode }) => testMode;
279
293
  //#endregion
280
- export { PACKAGE_VERSION, createFile, getDevCommand, getInstallUrl, isDirectoryEmpty, isPackageManagerAvailable, isTest, kvStores, logger, messageQueues, packageManagers, readTemplate, runtimes, throwUnlessNotExists };
294
+ export { PACKAGE_VERSION, createFile, getBuildCommand, getDevCommand, getInstallUrl, isDirectoryEmpty, isPackageManagerAvailable, isTest, kvStores, logger, messageQueues, packageManagers, readTemplate, runtimes, throwUnlessNotExists };
package/dist/mod.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { initCommand, initOptions } from "./command.js";
2
- import { runInit } from "./action/mod.js";
2
+ import runInit from "./action/mod.js";
3
3
  export { initCommand, initOptions, runInit };
@@ -1,4 +1,4 @@
1
- import bun from "@nurodev/astro-bun";
1
+ import node from "@astrojs/node";
2
2
  import { fedifyIntegration } from "@fedify/astro";
3
3
  import { defineConfig } from "astro/config";
4
4
 
@@ -6,5 +6,5 @@ import { defineConfig } from "astro/config";
6
6
  export default defineConfig({
7
7
  integrations: [fedifyIntegration()],
8
8
  output: "server",
9
- adapter: bun(),
9
+ adapter: node({ mode: "standalone" }),
10
10
  });
@@ -1,12 +1,12 @@
1
1
  import pm_default from "../json/pm.js";
2
2
  import { printErrorMessage, printMessage, product } from "../utils.js";
3
- import { kvStores, messageQueues } from "../lib.js";
3
+ import { getBuildCommand, kvStores, messageQueues } from "../lib.js";
4
4
  import webFrameworks from "../webframeworks/mod.js";
5
5
  import { filter, isEmpty, pipe, toArray } from "@fxts/core";
6
6
  import process from "node:process";
7
7
  import $ from "@david/dax";
8
- import { appendFile, mkdir, stat } from "node:fs/promises";
9
- import { join as join$1, sep } from "node:path";
8
+ import { appendFile, lstat, mkdir, readFile, stat, symlink } from "node:fs/promises";
9
+ import { dirname, join as join$1, resolve, sep } from "node:path";
10
10
  import { values } from "@optique/core";
11
11
  //#region src/test/create.ts
12
12
  const BANNED_PMS = ["bun", "yarn"];
@@ -16,7 +16,7 @@ const createTestApp = (testDirPrefix, dry) => async (options) => {
16
16
  const result = await $`${toArray(genInitCommand(testDir, dry, options))}`.cwd(join$1(import.meta.dirname, "..", "..")).stdin("null").stdout("piped").stderr("piped").noThrow().spawn();
17
17
  await saveOutputs(testDir, result);
18
18
  if (result.code === 0) {
19
- if (!dry && !await validateDevToolScripts(testDir, options)) {
19
+ if (!dry && (!await validateDevToolScripts(testDir, options) || !await validateFrameworkBuild(testDir, options))) {
20
20
  printMessage` Fail: ${vals}`;
21
21
  printMessage` Check out these files for more details: \
22
22
  ${join$1(testDir, "out.txt")} and \
@@ -74,17 +74,21 @@ const saveOutputs = async (dirPath, { stdout, stderr }) => {
74
74
  if (stderr) await appendFile(join$1(dirPath, "err.txt"), stderr + "\n", "utf8");
75
75
  };
76
76
  async function validateDevToolScripts(dir, options) {
77
- const [, packageManager] = options;
77
+ const [_, packageManager] = options;
78
78
  if (packageManager === "deno") return true;
79
79
  if (!await hasInstalledNodeDependencies(dir)) return true;
80
- for (const script of ["format:check", "lint"]) {
80
+ for (const script of [
81
+ "format",
82
+ "format:check",
83
+ "lint"
84
+ ]) {
81
85
  const result = await $`${[
82
86
  packageManager,
83
87
  "run",
84
88
  script
85
89
  ]}`.cwd(dir).stdin("null").stdout("piped").stderr("piped").noThrow().spawn();
86
90
  await saveOutputs(dir, result);
87
- if (result.code !== 0) return false;
91
+ if (result.code !== 0) printMessage` Warning: ${script} failed, continuing anyway.`;
88
92
  }
89
93
  return true;
90
94
  }
@@ -95,6 +99,27 @@ async function hasInstalledNodeDependencies(dir) {
95
99
  return false;
96
100
  }
97
101
  }
102
+ async function validateFrameworkBuild(dir, options) {
103
+ const [webFramework, packageManager] = options;
104
+ if (webFramework !== "astro") return true;
105
+ if (packageManager === "deno") await linkDenoWorkspacePackages(dir);
106
+ const result = await $`${getBuildCommand(packageManager)}`.cwd(dir).stdin("null").stdout("piped").stderr("piped").noThrow().spawn();
107
+ await saveOutputs(dir, result);
108
+ return result.code === 0;
109
+ }
110
+ async function linkDenoWorkspacePackages(dir) {
111
+ const config = JSON.parse(await readFile(join$1(dir, "deno.json"), "utf8"));
112
+ for (const link of config.links ?? []) {
113
+ const packageDir = resolve(dir, link);
114
+ const target = join$1(dir, "node_modules", ...JSON.parse(await readFile(join$1(packageDir, "package.json"), "utf8")).name.split("/"));
115
+ await mkdir(dirname(target), { recursive: true });
116
+ try {
117
+ await lstat(target);
118
+ } catch {
119
+ await symlink(packageDir, target, "junction");
120
+ }
121
+ }
122
+ }
98
123
  function filterOptions(options) {
99
124
  const [wf, pm, kv, mq] = options;
100
125
  return [
@@ -109,4 +109,4 @@ async function sendLookup(port) {
109
109
  return false;
110
110
  }
111
111
  //#endregion
112
- export { runServerAndLookupUser as default };
112
+ export { runServerAndLookupUser as default, isTestable, matchesLookupCasePattern, parseLookupCase };
package/dist/test/port.js CHANGED
@@ -90,7 +90,7 @@ const ENTRY_FILES = {
90
90
  hono: "src/index.ts",
91
91
  elysia: "src/index.ts"
92
92
  };
93
- const WF_READ_PORT_FROM_ENV = new Set([
93
+ const WF_READ_PORT_FROM_ENV = /* @__PURE__ */ new Set([
94
94
  "nuxt",
95
95
  "nitro",
96
96
  "solidstart"
@@ -127,4 +127,4 @@ async function ensurePortReleased(port) {
127
127
  }
128
128
  }
129
129
  //#endregion
130
- export { ensurePortReleased, killProcessOnPort, replacePortInApp, reservePort };
130
+ export { ensurePortReleased, isPortInUse, killProcessOnPort, replacePortInApp, reservePort, waitForPortRelease };
package/dist/types.d.ts CHANGED
@@ -125,4 +125,4 @@ interface InitCommandData extends InitCommandOptions {
125
125
  readonly env: Record<string, string>;
126
126
  }
127
127
  //#endregion
128
- export { InitCommandData };
128
+ export { InitCommandData, InitCommandOptions, KvStoreDescription, MessageQueueDescription, PackageManager, WebFrameworkInitializer };
package/dist/utils.js CHANGED
@@ -5,8 +5,14 @@ import { flow, toMerged } from "es-toolkit";
5
5
  import { message } from "@optique/core";
6
6
  import { Chalk } from "chalk";
7
7
  import { spawn } from "node:child_process";
8
+ //#region src/utils.ts
9
+ /**
10
+ * Whether terminal color output is enabled.
11
+ * `true` when stdout is a TTY and the `NO_COLOR` environment variable is not set.
12
+ */
13
+ const colorEnabled = process.stdout.isTTY && !("NO_COLOR" in process.env && process.env.NO_COLOR !== "");
8
14
  /** Chalk instance configured based on {@link colorEnabled}. */
9
- const colors = new Chalk(process.stdout.isTTY && !("NO_COLOR" in process.env && process.env.NO_COLOR !== "") ? {} : { level: 0 });
15
+ const colors = new Chalk(colorEnabled ? {} : { level: 0 });
10
16
  /** Type guard that checks whether a value is a `Promise`. */
11
17
  const isPromise = (value) => value instanceof Promise;
12
18
  /**
@@ -160,4 +166,4 @@ const printMessage = flow(message, print);
160
166
  /** Prints a formatted error message to stderr using `@optique/run`'s `printError`. */
161
167
  const printErrorMessage = flow(message, printError);
162
168
  //#endregion
163
- export { CommandError, colors, formatJson, getCwd, getOsType, isNotFoundError, merge$1 as merge, notEmpty, printErrorMessage, printMessage, product, replace, runSubCommand, set };
169
+ export { CommandError, colorEnabled, colors, formatJson, getCwd, getOsType, isNotFoundError, isPromise, merge$1 as merge, notEmpty, printErrorMessage, printMessage, product, replace, runSubCommand, set };
@@ -1,6 +1,6 @@
1
1
  import { PACKAGE_VERSION, readTemplate } from "../lib.js";
2
2
  import { PACKAGE_MANAGER } from "../const.js";
3
- import { npm__astrojs_node, npm__deno_astro_adapter, npm__dotenvx_dotenvx, npm__nurodev_astro_bun, npm__types_node_22, npm_oxlint, npm_prettier, npm_prettier_plugin_astro, npm_typescript } from "../json/deps.js";
3
+ import { "@logtape/logtape" as _logtape_logtape, "npm:@astrojs/node" as npm__astrojs_node, "npm:@deno/astro-adapter" as npm__deno_astro_adapter, "npm:@dotenvx/dotenvx" as npm__dotenvx_dotenvx, "npm:@types/node@22" as npm__types_node_22, "npm:astro" as npm_astro, "npm:create-astro" as npm_create_astro, "npm:oxlint" as npm_oxlint, "npm:prettier" as npm_prettier, "npm:prettier-plugin-astro" as npm_prettier_plugin_astro, "npm:typescript" as npm_typescript } from "../json/deps.js";
4
4
  import { defaultDenoDependencies } from "./const.js";
5
5
  import { getInstruction, pmToRt } from "./utils.js";
6
6
  //#region src/webframeworks/astro.ts
@@ -15,6 +15,14 @@ const astroNodeBunDevToolTasks = {
15
15
  "format:check": "prettier --plugin prettier-plugin-astro --check .",
16
16
  lint: "oxlint ."
17
17
  };
18
+ const astroDenoCommand = `deno run -A npm:astro@${npm_astro}`;
19
+ const ASTRO_NODE_VERSION_CHECK = `
20
+ const [major, minor] = process.versions.node.split(".").map(Number);
21
+ if (major < 22 || (major === 22 && minor < 12)) {
22
+ console.error("Astro 7 requires Node.js 22.12 or later.");
23
+ process.exit(1);
24
+ }
25
+ `.trim();
18
26
  const astroDescription = {
19
27
  label: "Astro",
20
28
  packageManagers: PACKAGE_MANAGER,
@@ -22,15 +30,21 @@ const astroDescription = {
22
30
  init: async ({ packageManager: pm }) => {
23
31
  const dependencies = pm === "deno" ? {
24
32
  ...defaultDenoDependencies,
33
+ "@fedify/fedify": `npm:@fedify/fedify@${PACKAGE_VERSION}`,
34
+ "@fedify/vocab": `npm:@fedify/vocab@${PACKAGE_VERSION}`,
35
+ "@logtape/logtape": `npm:@logtape/logtape@${_logtape_logtape}`,
36
+ astro: `npm:astro@${npm_astro}`,
25
37
  "@deno/astro-adapter": `npm:@deno/astro-adapter@${npm__deno_astro_adapter}`,
26
- "@fedify/astro": PACKAGE_VERSION
38
+ "@fedify/astro": `npm:@fedify/astro@${PACKAGE_VERSION}`
27
39
  } : pm === "bun" ? {
40
+ "@astrojs/node": npm__astrojs_node,
28
41
  "@fedify/astro": PACKAGE_VERSION,
29
- "@nurodev/astro-bun": npm__nurodev_astro_bun
42
+ astro: npm_astro
30
43
  } : {
31
44
  "@astrojs/node": npm__astrojs_node,
32
45
  "@fedify/astro": PACKAGE_VERSION,
33
- "@dotenvx/dotenvx": npm__dotenvx_dotenvx
46
+ "@dotenvx/dotenvx": npm__dotenvx_dotenvx,
47
+ astro: npm_astro
34
48
  };
35
49
  return {
36
50
  command: Array.from(getAstroInitCommand(pm)),
@@ -61,13 +75,21 @@ const astroDescription = {
61
75
  * by a template.
62
76
  */
63
77
  function* getAstroInitCommand(pm) {
78
+ if (pm !== "deno" && pm !== "bun") {
79
+ yield "node";
80
+ yield "-e";
81
+ yield ASTRO_NODE_VERSION_CHECK;
82
+ yield "&&";
83
+ }
64
84
  yield* createAstroAppCommand(pm);
65
- yield "astro@latest";
85
+ yield `astro@${npm_create_astro}`;
66
86
  yield ".";
67
87
  yield "--";
68
88
  yield "--no-git";
69
89
  yield "--skip-houston";
70
90
  yield "-y";
91
+ yield "--ref";
92
+ yield `astro@${npm_astro.replace(/^\D+/, "")}`;
71
93
  if (pm !== "deno") yield "--no-install";
72
94
  yield "&&";
73
95
  yield "rm";
@@ -82,9 +104,9 @@ const createAstroAppCommand = (pm) => pm === "deno" ? [
82
104
  ] : [pm, "create"];
83
105
  const TASKS = {
84
106
  "deno": {
85
- dev: "deno run -A npm:astro dev",
86
- build: "deno run -A npm:astro build",
87
- preview: "deno run -A npm:astro preview"
107
+ dev: `${astroDenoCommand} dev`,
108
+ build: `${astroDenoCommand} build`,
109
+ preview: `${astroDenoCommand} preview`
88
110
  },
89
111
  "bun": {
90
112
  dev: "bunx --bun astro dev",
@@ -1,6 +1,6 @@
1
1
  import { readTemplate } from "../lib.js";
2
2
  import { PACKAGE_MANAGER } from "../const.js";
3
- import { _hongminhee_x_forwarded_fetch, npm__dotenvx_dotenvx, npm__hono_node_server, npm__types_bun, npm__types_node_25, npm_tsx, npm_x_forwarded_fetch } from "../json/deps.js";
3
+ import { "@hongminhee/x-forwarded-fetch" as _hongminhee_x_forwarded_fetch, "npm:@dotenvx/dotenvx" as npm__dotenvx_dotenvx, "npm:@hono/node-server" as npm__hono_node_server, "npm:@types/bun" as npm__types_bun, "npm:@types/node@25" as npm__types_node_25, "npm:tsx" as npm_tsx, "npm:x-forwarded-fetch" as npm_x_forwarded_fetch } from "../json/deps.js";
4
4
  import { defaultDenoDependencies, defaultDevDependencies } from "./const.js";
5
5
  import { getInstruction, nodeBunDevToolTasks, pmToRt } from "./utils.js";
6
6
  //#region src/webframeworks/bare-bones.ts
@@ -1,5 +1,5 @@
1
1
  import { PACKAGE_VERSION } from "../lib.js";
2
- import { npm_oxfmt, npm_oxlint } from "../json/deps.js";
2
+ import { "npm:oxfmt" as npm_oxfmt, "npm:oxlint" as npm_oxlint } from "../json/deps.js";
3
3
  //#region src/webframeworks/const.ts
4
4
  const defaultDevDependencies = {
5
5
  "@fedify/lint": PACKAGE_VERSION,
@@ -1,6 +1,6 @@
1
1
  import { PACKAGE_VERSION, readTemplate } from "../lib.js";
2
2
  import { PACKAGE_MANAGER } from "../const.js";
3
- import { npm__dotenvx_dotenvx, npm__elysiajs_node, npm__sinclair_typebox, npm__types_bun, npm__types_node_25, npm_elysia, npm_openapi_types, npm_tsx, npm_typescript } from "../json/deps.js";
3
+ import { "npm:@dotenvx/dotenvx" as npm__dotenvx_dotenvx, "npm:@elysiajs/node" as npm__elysiajs_node, "npm:@sinclair/typebox" as npm__sinclair_typebox, "npm:@types/bun" as npm__types_bun, "npm:@types/node@25" as npm__types_node_25, "npm:elysia" as npm_elysia, "npm:openapi-types" as npm_openapi_types, "npm:tsx" as npm_tsx, "npm:typescript" as npm_typescript } from "../json/deps.js";
4
4
  import { defaultDenoDependencies, defaultDevDependencies } from "./const.js";
5
5
  import { getInstruction, nodeBunDevToolTasks, pmToRt } from "./utils.js";
6
6
  //#region src/webframeworks/elysia.ts
@@ -1,6 +1,6 @@
1
1
  import { PACKAGE_VERSION, readTemplate } from "../lib.js";
2
2
  import { PACKAGE_MANAGER } from "../const.js";
3
- import { npm__dotenvx_dotenvx, npm__types_bun, npm__types_express, npm_express, npm_tsx } from "../json/deps.js";
3
+ import { "npm:@dotenvx/dotenvx" as npm__dotenvx_dotenvx, "npm:@types/bun" as npm__types_bun, "npm:@types/express" as npm__types_express, "npm:express" as npm_express, "npm:tsx" as npm_tsx } from "../json/deps.js";
4
4
  import { defaultDenoDependencies, defaultDevDependencies } from "./const.js";
5
5
  import { getInstruction, nodeBunDevToolTasks, pmToRt } from "./utils.js";
6
6
  //#region src/webframeworks/express.ts
@@ -1,7 +1,7 @@
1
1
  import { replace } from "../utils.js";
2
2
  import { PACKAGE_VERSION, readTemplate } from "../lib.js";
3
3
  import { PACKAGE_MANAGER } from "../const.js";
4
- import { _hongminhee_x_forwarded_fetch, _hono_hono, npm__dotenvx_dotenvx, npm__hono_node_server, npm__types_bun, npm_hono, npm_tsx, npm_x_forwarded_fetch } from "../json/deps.js";
4
+ import { "@hongminhee/x-forwarded-fetch" as _hongminhee_x_forwarded_fetch, "@hono/hono" as _hono_hono, "npm:@dotenvx/dotenvx" as npm__dotenvx_dotenvx, "npm:@hono/node-server" as npm__hono_node_server, "npm:@types/bun" as npm__types_bun, "npm:hono" as npm_hono, "npm:tsx" as npm_tsx, "npm:x-forwarded-fetch" as npm_x_forwarded_fetch } from "../json/deps.js";
5
5
  import { defaultDenoDependencies, defaultDevDependencies } from "./const.js";
6
6
  import { getInstruction, nodeBunDevToolTasks, pmToRt } from "./utils.js";
7
7
  import { pipe } from "@fxts/core";
@@ -1,6 +1,6 @@
1
1
  import { PACKAGE_VERSION, readTemplate } from "../lib.js";
2
2
  import { PACKAGE_MANAGER } from "../const.js";
3
- import { npm__types_node_20 } from "../json/deps.js";
3
+ import { "npm:@types/node@20" as npm__types_node_20 } from "../json/deps.js";
4
4
  import { defaultDenoDependencies, defaultDevDependencies } from "./const.js";
5
5
  import { getInstruction, getNodeBunDevToolTasks } from "./utils.js";
6
6
  //#region src/webframeworks/next.ts
@@ -1,6 +1,6 @@
1
1
  import { PACKAGE_VERSION, readTemplate } from "../lib.js";
2
2
  import { PACKAGE_MANAGER } from "../const.js";
3
- import { npm__types_node_25, npm_typescript } from "../json/deps.js";
3
+ import { "npm:@types/node@25" as npm__types_node_25, "npm:typescript" as npm_typescript } from "../json/deps.js";
4
4
  import { defaultDenoDependencies, defaultDevDependencies } from "./const.js";
5
5
  import { getInstruction, getNodeBunDevToolTasks } from "./utils.js";
6
6
  //#region src/webframeworks/nuxt.ts
@@ -1,6 +1,6 @@
1
1
  import { PACKAGE_VERSION, readTemplate } from "../lib.js";
2
2
  import { PACKAGE_MANAGER } from "../const.js";
3
- import { npm__dotenvx_dotenvx, npm__solidjs_router, npm__solidjs_start, npm__types_node_22, npm_solid_js, npm_typescript, npm_vinxi } from "../json/deps.js";
3
+ import { "npm:@dotenvx/dotenvx" as npm__dotenvx_dotenvx, "npm:@solidjs/router" as npm__solidjs_router, "npm:@solidjs/start" as npm__solidjs_start, "npm:@types/node@22" as npm__types_node_22, "npm:solid-js" as npm_solid_js, "npm:typescript" as npm_typescript, "npm:vinxi" as npm_vinxi } from "../json/deps.js";
4
4
  import { defaultDenoDependencies, defaultDevDependencies } from "./const.js";
5
5
  import { getInstruction, nodeBunDevToolTasks, pmToRt } from "./utils.js";
6
6
  //#region src/webframeworks/solidstart.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fedify/init",
3
- "version": "2.4.0-dev.1666+690d9b28",
3
+ "version": "2.4.0-dev.1727+1eadcb04",
4
4
  "description": "Project initializer for Fedify",
5
5
  "keywords": [
6
6
  "fedify",
@@ -46,7 +46,7 @@
46
46
  ],
47
47
  "dependencies": {
48
48
  "@david/dax": "npm:dax@^0.46.1",
49
- "@fxts/core": "^1.20.0",
49
+ "@fxts/core": "^1.21.1",
50
50
  "@inquirer/prompts": "^7.8.4",
51
51
  "@logtape/logtape": "^2.2.0",
52
52
  "@optique/core": "^1.1.0",