diff --git a/packages/init/src/action/configs.test.ts b/packages/init/src/action/configs.test.ts index c63d31730..ef6190fcd 100644 --- a/packages/init/src/action/configs.test.ts +++ b/packages/init/src/action/configs.test.ts @@ -7,6 +7,7 @@ import { message } from "@optique/core"; import { kvStores, messageQueues } from "../lib.ts"; import type { InitCommandData } from "../types.ts"; import bareBonesDescription from "../webframeworks/bare-bones.ts"; +import nuxtDescription from "../webframeworks/nuxt.ts"; import { loadDenoConfig } from "./configs.ts"; import { patchFiles } from "./patch.ts"; @@ -133,6 +134,28 @@ test("patchFiles creates a Biome config matching the npm package version", async } }); +test("patchFiles wires Nuxt logging through a Nitro plugin", async () => { + const dir = await mkdtemp(join(tmpdir(), "fedify-init-nuxt-")); + + try { + const data = await createNuxtNpmInitData(dir); + await patchFiles(data); + + const logging = await readFile(join(dir, "server/logging.ts"), "utf8"); + const plugin = await readFile( + join(dir, "server/plugins/logging.ts"), + "utf8", + ); + + assert.match(logging, /export default configure\(/); + assert.doesNotMatch(logging, /await configure\(/); + assert.match(plugin, /import loggingConfigured from "\.\.\/logging";/); + assert.match(plugin, /await loggingConfigured;/); + } finally { + await rm(dir, { recursive: true, force: true }); + } +}); + async function createNpmInitData(dir: string): Promise { const initializer = await bareBonesDescription.init({ command: "init", @@ -166,6 +189,39 @@ async function createNpmInitData(dir: string): Promise { return data; } +async function createNuxtNpmInitData(dir: string): Promise { + const initializer = await nuxtDescription.init({ + command: "init", + projectName: "example", + packageManager: "npm", + webFramework: "nuxt", + kvStore: "in-memory", + messageQueue: "in-process", + dryRun: false, + allowNonEmpty: false, + testMode: false, + dir, + }); + + const data = { + command: "init", + projectName: "example", + packageManager: "npm", + webFramework: "nuxt", + kvStore: "in-memory", + messageQueue: "in-process", + dryRun: false, + allowNonEmpty: false, + testMode: false, + dir, + initializer, + kv: kvStores["in-memory"], + mq: messageQueues["in-process"], + env: {}, + } satisfies InitCommandData; + return data; +} + function getSchemaVersion(schema: string): string { const match = schema.match(/\/schemas\/(\d+\.\d+\.\d+)\//); assert.ok(match, `Unexpected Biome schema URL: ${schema}`); diff --git a/packages/init/src/action/templates.ts b/packages/init/src/action/templates.ts index 8e489c11e..813c0d327 100644 --- a/packages/init/src/action/templates.ts +++ b/packages/init/src/action/templates.ts @@ -38,9 +38,11 @@ export const loadFederation = async ( * @param param0 - Destructured object containing the project name * @returns The complete logging configuration file content as a string */ -export const loadLogging = async ({ projectName }: InitCommandData) => +export const loadLogging = async ( + { projectName, initializer }: InitCommandData, +) => pipe( - await readTemplate("defaults/logging.ts"), + await readTemplate(initializer.loggingTemplate ?? "defaults/logging.ts"), replace(/\/\* project name \*\//, JSON.stringify(projectName)), ); diff --git a/packages/init/src/templates/nuxt/server/logging.ts.tpl b/packages/init/src/templates/nuxt/server/logging.ts.tpl new file mode 100644 index 000000000..3eabb10c4 --- /dev/null +++ b/packages/init/src/templates/nuxt/server/logging.ts.tpl @@ -0,0 +1,23 @@ +import { configure, getConsoleSink } from "@logtape/logtape"; +import { AsyncLocalStorage } from "node:async_hooks"; + +export default configure({ + contextLocalStorage: new AsyncLocalStorage(), + sinks: { + console: getConsoleSink(), + }, + filters: {}, + loggers: [ + { + category: /* project name */, + lowestLevel: "debug", + sinks: ["console"], + }, + { category: "fedify", lowestLevel: "info", sinks: ["console"] }, + { + category: ["logtape", "meta"], + lowestLevel: "warning", + sinks: ["console"], + }, + ], +}); diff --git a/packages/init/src/templates/nuxt/server/plugins/logging.ts.tpl b/packages/init/src/templates/nuxt/server/plugins/logging.ts.tpl new file mode 100644 index 000000000..e52d96936 --- /dev/null +++ b/packages/init/src/templates/nuxt/server/plugins/logging.ts.tpl @@ -0,0 +1,5 @@ +import loggingConfigured from "../logging"; + +export default defineNitroPlugin(async () => { + await loggingConfigured; +}); diff --git a/packages/init/src/types.ts b/packages/init/src/types.ts index fb46c9f0e..479c184e9 100644 --- a/packages/init/src/types.ts +++ b/packages/init/src/types.ts @@ -78,6 +78,8 @@ export interface WebFrameworkInitializer { federationFile: string; /** Relative path where the logging configuration file will be created. */ loggingFile: string; + /** Optional template path for the logging configuration file. */ + loggingTemplate?: string; /** * Additional files to create, keyed by relative path to file content. * Do not use `".env"` as a key — use the {@link env} property instead so diff --git a/packages/init/src/webframeworks/nuxt.ts b/packages/init/src/webframeworks/nuxt.ts index 2e02f4187..083e6d672 100644 --- a/packages/init/src/webframeworks/nuxt.ts +++ b/packages/init/src/webframeworks/nuxt.ts @@ -19,9 +19,13 @@ const nuxtDescription: WebFrameworkDescription = { }, federationFile: "server/federation.ts", loggingFile: "server/logging.ts", + loggingTemplate: "nuxt/server/logging.ts", env: testMode ? { HOST: "127.0.0.1" } : {} as Record, files: { "nuxt.config.ts": await readTemplate("nuxt/nuxt.config.ts"), + "server/plugins/logging.ts": await readTemplate( + "nuxt/server/plugins/logging.ts", + ), ...(pm !== "deno" && { "eslint.config.ts": await readTemplate("defaults/eslint.config.ts"), }),