@witchcraft/nuxt-logger 0.0.12 → 0.1.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 (33) hide show
  1. package/README.md +11 -2
  2. package/dist/module.json +3 -3
  3. package/dist/module.mjs +4 -3
  4. package/dist/runtime/electron/index.d.ts +1 -4
  5. package/dist/runtime/electron/index.js +0 -3
  6. package/dist/runtime/electron/main/index.d.ts +3 -0
  7. package/dist/runtime/electron/main/index.js +3 -0
  8. package/dist/runtime/electron/{receiveFromRendererOnMain.js → main/receiveFromRendererOnMain.js} +1 -1
  9. package/dist/runtime/electron/{useElectronLogger.d.ts → main/useElectronLogger.d.ts} +4 -2
  10. package/dist/runtime/electron/{useElectronLogger.js → main/useElectronLogger.js} +5 -5
  11. package/dist/runtime/electron/{createElectronLoggerApi.d.ts → preload/createElectronLoggerApi.d.ts} +1 -1
  12. package/dist/runtime/electron/preload/createElectronLoggerApi.js +19 -0
  13. package/dist/runtime/electron/preload/index.d.ts +1 -0
  14. package/dist/runtime/electron/preload/index.js +1 -0
  15. package/dist/runtime/helpers/getBaseOptions.js +1 -1
  16. package/dist/runtime/plugins/init.js +2 -1
  17. package/dist/runtime/shared/createUseLogger.js +12 -2
  18. package/package.json +18 -10
  19. package/src/module.ts +4 -3
  20. package/src/runtime/electron/index.ts +1 -6
  21. package/src/runtime/electron/main/index.ts +3 -0
  22. package/src/runtime/electron/{receiveFromRendererOnMain.ts → main/receiveFromRendererOnMain.ts} +2 -1
  23. package/src/runtime/electron/{useElectronLogger.ts → main/useElectronLogger.ts} +12 -8
  24. package/src/runtime/electron/{wrapLoggerForElectron.ts → main/wrapLoggerForElectron.ts} +4 -4
  25. package/src/runtime/electron/{createElectronLoggerApi.ts → preload/createElectronLoggerApi.ts} +9 -4
  26. package/src/runtime/electron/preload/index.ts +1 -0
  27. package/src/runtime/helpers/getBaseOptions.ts +3 -1
  28. package/src/runtime/plugins/init.ts +3 -1
  29. package/src/runtime/shared/createUseLogger.ts +12 -2
  30. package/dist/runtime/electron/createElectronLoggerApi.js +0 -13
  31. /package/dist/runtime/electron/{receiveFromRendererOnMain.d.ts → main/receiveFromRendererOnMain.d.ts} +0 -0
  32. /package/dist/runtime/electron/{wrapLoggerForElectron.d.ts → main/wrapLoggerForElectron.d.ts} +0 -0
  33. /package/dist/runtime/electron/{wrapLoggerForElectron.js → main/wrapLoggerForElectron.js} +0 -0
package/README.md CHANGED
@@ -42,6 +42,14 @@ By default redacts some known sensitive keys for the middleware logging requests
42
42
 
43
43
  Also redacts the `redact` key, but only in production, so you can put anything semi-sensitive in there that you need to inspect in development.
44
44
 
45
+ ### Server transports
46
+
47
+ On the server the module adds two transports by default, file logging to `logPath` and pretty console logs through `pino-pretty`.
48
+
49
+ Pino resolves the pretty transport at runtime from your app, not from this package. With strict dependency isolation (pnpm) or a bundled server (Nitro), that lookup fails and the server crashes with `unable to determine transport target for "pino-pretty"`. Give the app a copy it can find by adding `pino-pretty` to your app dependencies, or turn the pretty transport off with `disabledServerTransportTargets: ["pino-pretty"]`.
50
+
51
+ In dev the module warns and keeps running without pretty console logs when `pino-pretty` cannot be resolved.
52
+
45
53
  ### Electron
46
54
 
47
55
  The electron logger requires a bit of setup since electron's main cannot be passed the runtime config normally.
@@ -52,7 +60,8 @@ This assumes the usage of
52
60
  There is a full example in the [@witchcraft/nuxt-electron playground](TODO).
53
61
 
54
62
  ```ts [main.ts]
55
- import { STATIC, useDevDataDir } from "@witchcraft/nuxt-electron/electron"
63
+ import { useDevDataDir } from "@witchcraft/nuxt-electron/electron/main"
64
+ import { STATIC } from "@witchcraft/nuxt-electron/electron"
56
65
  import { ELECTRON } from "@witchcraft/nuxt-logger/electron"
57
66
 
58
67
  // assuming you stick your active window instances here
@@ -84,7 +93,7 @@ We can setup the apis for two way communication in the preload script.
84
93
  ```ts
85
94
  // preload.ts
86
95
  import { contextBridge, ipcRenderer } from "electron"
87
- import { createElectronLoggerApi, type ElectronLoggerApi } from "@witchcraft/nuxt-logger/electron"
96
+ import { createElectronLoggerApi, type ElectronLoggerApi } from "@witchcraft/nuxt-logger/electron/preload"
88
97
 
89
98
  declare global {
90
99
  interface Window {
package/dist/module.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "logger",
3
3
  "configKey": "logger",
4
- "version": "0.0.12",
4
+ "version": "0.1.1",
5
5
  "builder": {
6
- "@nuxt/module-builder": "1.0.2",
7
- "unbuild": "3.6.1"
6
+ "@nuxt/module-builder": "1.0.3",
7
+ "unbuild": "unknown"
8
8
  }
9
9
  }
package/dist/module.mjs CHANGED
@@ -81,9 +81,10 @@ const module$1 = defineNuxtModule({
81
81
  addPlugin(resolve("./runtime/plugins/init"));
82
82
  nuxt.options.alias["#logger"] = resolve("./runtime");
83
83
  nuxt.hook("vite:extendConfig", (config) => {
84
- config.optimizeDeps ??= {};
85
- config.optimizeDeps.include ??= [];
86
- config.optimizeDeps.include.push("pino");
84
+ const optimizeDeps = config.optimizeDeps ?? {};
85
+ optimizeDeps.include ??= [];
86
+ optimizeDeps.include.push("pino");
87
+ Object.assign(config, { optimizeDeps });
87
88
  });
88
89
  }
89
90
  });
@@ -1,4 +1 @@
1
- export { createElectronLoggerApi, type ElectronLoggerApi } from "./createElectronLoggerApi";
2
- export { useElectronLogger } from "./useElectronLogger";
3
- export { wrapLoggerForElectron } from "./wrapLoggerForElectron";
4
- export * from "./types";
1
+ export * from "./types.js";
@@ -1,4 +1 @@
1
- export { createElectronLoggerApi } from "./createElectronLoggerApi.js";
2
- export { useElectronLogger } from "./useElectronLogger.js";
3
- export { wrapLoggerForElectron } from "./wrapLoggerForElectron.js";
4
1
  export * from "./types.js";
@@ -0,0 +1,3 @@
1
+ export { receiveFromRendererOnMain } from "./receiveFromRendererOnMain.js";
2
+ export { useElectronLogger } from "./useElectronLogger.js";
3
+ export { wrapLoggerForElectron } from "./wrapLoggerForElectron.js";
@@ -0,0 +1,3 @@
1
+ export { receiveFromRendererOnMain } from "./receiveFromRendererOnMain.js";
2
+ export { useElectronLogger } from "./useElectronLogger.js";
3
+ export { wrapLoggerForElectron } from "./wrapLoggerForElectron.js";
@@ -1,5 +1,5 @@
1
1
  import { ipcMain } from "electron";
2
- import { ELECTRON_LOG_TYPE } from "./types.js";
2
+ import { ELECTRON_LOG_TYPE } from "../types.js";
3
3
  export function receiveFromRendererOnMain(logger) {
4
4
  ipcMain.on(ELECTRON_LOG_TYPE.TO_MAIN, (_event, message) => {
5
5
  if (typeof message.data === "object" && typeof message.level === "string") {
@@ -1,5 +1,6 @@
1
1
  import type { PublicRuntimeConfig } from "@nuxt/schema";
2
2
  import { type BrowserWindow } from "electron";
3
+ import pino from "pino";
3
4
  /**
4
5
  * A simplified wrapper around pino for use in electron main. Note that it does not support child logger and is actually a simple wrapper around just the basic levels.
5
6
  *
@@ -9,10 +10,11 @@ import { type BrowserWindow } from "electron";
9
10
  * - We can't use useRuntimeConfig so it's injected by using vite define instead ({@link STATIC}).
10
11
  * - We need to pass the logPath which is defined at runtime.
11
12
  * - We need to use some electron only imports which causes problems for the regular server.
12
- * - Pino needs to be told were to find it's workers electron side in prod.
13
+ * - Pino needs to be told were to find it's workers electron side in prod both when using a packed asar and when not.
13
14
  * {@link https://github.com/pinojs/pino/blob/master/docs/bundling.md}
14
15
  * Using vite's ?worker&url imports almost works (the paths are correct) but something about the transpiling breaks things I think.
16
+ *
15
17
  */
16
18
  export declare function useElectronLogger(pinoConfig?: PublicRuntimeConfig["logger"], windows?: () => BrowserWindow[], { receiveFromRenderer }?: {
17
19
  receiveFromRenderer?: boolean;
18
- }): Record<keyof import("pino").BaseLogger | keyof import("pino").LoggerExtras<never, boolean> | "customLevels" | "useOnlyCustomLevels", (data: any) => void>;
20
+ }): Record<keyof pino.BaseLogger | keyof pino.LoggerExtras<never, boolean> | "customLevels" | "useOnlyCustomLevels", (data: any) => void>;
@@ -1,11 +1,12 @@
1
1
  import { keys } from "@alanscodelog/utils/keys";
2
2
  import { app } from "electron";
3
3
  import path from "node:path";
4
- import { pino } from "pino";
4
+ import pino from "pino";
5
5
  import { receiveFromRendererOnMain } from "./receiveFromRendererOnMain.js";
6
- import { ELECTRON_LOG_TYPE } from "./types.js";
7
- import { getBaseOptions } from "../helpers/getBaseOptions.js";
6
+ import { getBaseOptions } from "../../helpers/getBaseOptions.js";
7
+ import { ELECTRON_LOG_TYPE } from "../types.js";
8
8
  globalThis.__bundlerPathsOverrides = {
9
+ nodeModulesLocation: app.getAppPath(),
9
10
  "pino-worker": `./node_modules/pino/lib/worker.js`,
10
11
  "pino-worker-pipeline": `./node_modules/pino/lib/worker-pipeline.js`,
11
12
  "thread-stream-worker": `./node_modules/thread-stream/lib/worker.js`,
@@ -13,9 +14,8 @@ globalThis.__bundlerPathsOverrides = {
13
14
  "pino-pretty": `./node_modules/pino-pretty/index.js`
14
15
  };
15
16
  const bundlerOverrides = globalThis.__bundlerPathsOverrides;
16
- const appPath = app.getAppPath();
17
17
  for (const key of keys(bundlerOverrides)) {
18
- bundlerOverrides[key] = path.resolve(appPath, bundlerOverrides[key]);
18
+ bundlerOverrides[key] = path.resolve(bundleOverrides.nodeModulesLocation, bundlerOverrides[key]);
19
19
  }
20
20
  let initiated = false;
21
21
  const levels = ["error", "warn", "debug", "trace", "info", "fatal"];
@@ -1,5 +1,5 @@
1
1
  import type { ipcRenderer as IpcRenderer } from "electron";
2
- import type { Levels } from "../types.js";
2
+ import type { Levels } from "../../types.js";
3
3
  export type ElectronLoggerApi = {
4
4
  log: (level: Levels, data: any) => void;
5
5
  _logs: {
@@ -0,0 +1,19 @@
1
+ import { ELECTRON_LOG_TYPE } from "../types.js";
2
+ export function createElectronLoggerApi(ipcRenderer) {
3
+ return {
4
+ log: (level, data) => {
5
+ try {
6
+ ipcRenderer.send(ELECTRON_LOG_TYPE.TO_MAIN, { level, data });
7
+ } catch (error) {
8
+ throw new Error(`[nuxt-logger] could not forward a "${level}" log to electron's main process, its payload must be cloneable, pass raw values (e.g. \`toRaw\` on a reactive object). Log: ${JSON.stringify(data)}`, { cause: error });
9
+ }
10
+ },
11
+ _logs: {
12
+ on(cb) {
13
+ ipcRenderer.on(ELECTRON_LOG_TYPE.FROM_MAIN_ON_RENDERER, (_event, level, data) => {
14
+ cb(level, data);
15
+ });
16
+ }
17
+ }
18
+ };
19
+ }
@@ -0,0 +1 @@
1
+ export { createElectronLoggerApi, type ElectronLoggerApi } from "./createElectronLoggerApi.js";
@@ -0,0 +1 @@
1
+ export { createElectronLoggerApi } from "./createElectronLoggerApi.js";
@@ -90,7 +90,7 @@ export function getBaseOptions(config, serverPathResolver) {
90
90
  send: (level, logEvent) => {
91
91
  if (!logEvent.messages[0]?.ns?.startsWith("main") && levels.values[level] < levels.values[writeLevel]) {
92
92
  logEvent.messages[0].ns &&= `renderer:${logEvent.messages[0].ns}`;
93
- window.electron.api.log(logEvent);
93
+ window.electron.api.log(level, logEvent);
94
94
  }
95
95
  }
96
96
  } : void 0
@@ -1,3 +1,4 @@
1
+ import { toRaw } from "vue";
1
2
  import { defineNuxtPlugin, useRuntimeConfig } from "#imports";
2
3
  import { useLogger } from "../composables/useLogger.js";
3
4
  export default defineNuxtPlugin({
@@ -5,7 +6,7 @@ export default defineNuxtPlugin({
5
6
  setup(nuxtApp) {
6
7
  if (import.meta.client) {
7
8
  nuxtApp.hook("app:created", () => {
8
- const config = useRuntimeConfig().public;
9
+ const config = toRaw(useRuntimeConfig().public);
9
10
  const initialLog = { appInfo: config.appInfo };
10
11
  if (window.navigator !== void 0) {
11
12
  initialLog.environmentInfo = {
@@ -1,4 +1,4 @@
1
- import { pino } from "pino";
1
+ import pino from "pino";
2
2
  import { getBaseOptions } from "../helpers/getBaseOptions.js";
3
3
  const logger = {};
4
4
  export function createUseLogger(rc, serverPathResolver) {
@@ -14,7 +14,17 @@ export function createUseLogger(rc, serverPathResolver) {
14
14
  const { opts, transports, browserOpts, debug } = getBaseOptions(config.logger, serverPathResolver);
15
15
  let transport;
16
16
  if (import.meta.server) {
17
- transport = pino.transport(transports);
17
+ try {
18
+ transport = pino.transport(transports);
19
+ } catch (e) {
20
+ const missingTarget = /unable to determine transport target for "([^"]+)"/.exec(e?.message ?? "")?.[1];
21
+ if (import.meta.dev && missingTarget === "pino-pretty") {
22
+ console.warn(`[nuxt-logger] "pino-pretty" could not be resolved, pretty console logs are disabled. Add "pino-pretty" to your app dependencies or set disabledServerTransportTargets: ["pino-pretty"].`);
23
+ transport = pino.transport({ targets: transports.targets.filter((t) => t.target !== "pino-pretty") });
24
+ } else {
25
+ throw e;
26
+ }
27
+ }
18
28
  }
19
29
  const pinoLogger = pino(
20
30
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@witchcraft/nuxt-logger",
3
- "version": "0.0.12",
3
+ "version": "0.1.1",
4
4
  "description": "Nuxt module for logging.",
5
5
  "repository": "witchcraftjs/nuxt-logger",
6
6
  "license": "MIT",
@@ -11,13 +11,21 @@
11
11
  "types": "./dist/types.d.mts",
12
12
  "import": "./dist/module.mjs"
13
13
  },
14
- "./*": {
15
- "types": "./dist/runtime/*.d.ts",
16
- "import": "./dist/runtime/*.js"
17
- },
18
14
  "./electron": {
19
15
  "types": "./dist/runtime/electron/index.d.ts",
20
16
  "import": "./dist/runtime/electron/index.js"
17
+ },
18
+ "./electron/main": {
19
+ "types": "./dist/runtime/electron/main/index.d.ts",
20
+ "import": "./dist/runtime/electron/main/index.js"
21
+ },
22
+ "./electron/preload": {
23
+ "types": "./dist/runtime/electron/preload/index.d.ts",
24
+ "import": "./dist/runtime/electron/preload/index.js"
25
+ },
26
+ "./*": {
27
+ "types": "./dist/runtime/*.d.ts",
28
+ "import": "./dist/runtime/*.js"
21
29
  }
22
30
  },
23
31
  "files": [
@@ -30,18 +38,18 @@
30
38
  "pino-pretty": "^11.2.2"
31
39
  },
32
40
  "dependencies": {
33
- "@alanscodelog/tsconfigs": "^6.3.0",
34
- "@alanscodelog/utils": "^6.2.0",
41
+ "@alanscodelog/tsconfigs": "^6.3.1",
42
+ "@alanscodelog/utils": "^6.3.0",
35
43
  "@nuxt/kit": "^4.3.1",
36
44
  "defu": "latest",
37
45
  "pino": "^9.9.0",
38
46
  "pino-pretty": "^11.3.0"
39
47
  },
40
48
  "devDependencies": {
41
- "@alanscodelog/eslint-config": "^6.3.1",
42
- "@alanscodelog/semantic-release-config": "^6.0.2",
49
+ "@alanscodelog/eslint-config": "^6.3.2",
50
+ "@alanscodelog/semantic-release-config": "^6.0.3",
43
51
  "@nuxt/eslint-config": "^1.15.2",
44
- "@nuxt/module-builder": "^1.0.2",
52
+ "@nuxt/module-builder": "^1.0.3",
45
53
  "@nuxt/schema": "^4.3.1",
46
54
  "@nuxt/test-utils": "^3.19.2",
47
55
  "@types/node": "latest",
package/src/module.ts CHANGED
@@ -171,9 +171,10 @@ export default defineNuxtModule<ModuleOptions>({
171
171
  nuxt.options.alias["#logger"] = resolve("./runtime")
172
172
  nuxt.hook("vite:extendConfig", config => {
173
173
  // fixes https://github.com/nuxt/nuxt/issues/13247 partially (also transpiling it breaks it)
174
- config.optimizeDeps ??= {}
175
- config.optimizeDeps.include ??= []
176
- config.optimizeDeps.include.push("pino")
174
+ const optimizeDeps = config.optimizeDeps ?? {}
175
+ optimizeDeps.include ??= []
176
+ optimizeDeps.include.push("pino")
177
+ Object.assign(config, { optimizeDeps })
177
178
  })
178
179
  }
179
180
  })
@@ -1,6 +1 @@
1
- // note adding file endings breaks build types
2
- export { createElectronLoggerApi, type ElectronLoggerApi } from "./createElectronLoggerApi"
3
-
4
- export { useElectronLogger } from "./useElectronLogger"
5
- export { wrapLoggerForElectron } from "./wrapLoggerForElectron"
6
- export * from "./types"
1
+ export * from "./types.js"
@@ -0,0 +1,3 @@
1
+ export { receiveFromRendererOnMain } from "./receiveFromRendererOnMain.js"
2
+ export { useElectronLogger } from "./useElectronLogger.js"
3
+ export { wrapLoggerForElectron } from "./wrapLoggerForElectron.js"
@@ -1,8 +1,9 @@
1
1
  import { ipcMain } from "electron"
2
2
 
3
- import { ELECTRON_LOG_TYPE } from "./types.js"
4
3
  import type { useElectronLogger } from "./useElectronLogger.js"
5
4
 
5
+ import { ELECTRON_LOG_TYPE } from "../types.js"
6
+
6
7
  export function receiveFromRendererOnMain(logger: ReturnType<typeof useElectronLogger>): void {
7
8
  ipcMain.on(ELECTRON_LOG_TYPE.TO_MAIN, (_event, message) => {
8
9
  if (typeof message.data === "object" && typeof message.level === "string") {
@@ -2,15 +2,16 @@ import { keys } from "@alanscodelog/utils/keys"
2
2
  import type { PublicRuntimeConfig } from "@nuxt/schema"
3
3
  import { app, type BrowserWindow } from "electron"
4
4
  import path from "node:path"
5
- import { type Logger, pino } from "pino"
5
+ import pino, { type Logger } from "pino"
6
6
 
7
7
  import { receiveFromRendererOnMain } from "./receiveFromRendererOnMain.js"
8
- import { ELECTRON_LOG_TYPE } from "./types.js"
9
8
 
10
- import { getBaseOptions } from "../helpers/getBaseOptions.js"
9
+ import { getBaseOptions } from "../../helpers/getBaseOptions.js"
10
+ import { ELECTRON_LOG_TYPE } from "../types.js"
11
11
 
12
12
  declare const globalThis: any
13
13
  globalThis.__bundlerPathsOverrides = {
14
+ nodeModulesLocation: app.getAppPath(),
14
15
  "pino-worker": `./node_modules/pino/lib/worker.js`,
15
16
  "pino-worker-pipeline": `./node_modules/pino/lib/worker-pipeline.js`,
16
17
  "thread-stream-worker": `./node_modules/thread-stream/lib/worker.js`,
@@ -19,9 +20,8 @@ globalThis.__bundlerPathsOverrides = {
19
20
  }
20
21
  const bundlerOverrides = globalThis.__bundlerPathsOverrides
21
22
 
22
- const appPath = app.getAppPath()
23
23
  for (const key of keys(bundlerOverrides)) {
24
- bundlerOverrides[key] = path.resolve(appPath, bundlerOverrides[key])
24
+ bundlerOverrides[key] = path.resolve(bundleOverrides.nodeModulesLocation, bundlerOverrides[key])
25
25
  }
26
26
 
27
27
  let initiated = false
@@ -37,16 +37,20 @@ const logger: Record<typeof levels[number], ((data: any) => void)> = {} as any
37
37
  * - We can't use useRuntimeConfig so it's injected by using vite define instead ({@link STATIC}).
38
38
  * - We need to pass the logPath which is defined at runtime.
39
39
  * - We need to use some electron only imports which causes problems for the regular server.
40
- * - Pino needs to be told were to find it's workers electron side in prod.
40
+ * - Pino needs to be told were to find it's workers electron side in prod both when using a packed asar and when not.
41
41
  * {@link https://github.com/pinojs/pino/blob/master/docs/bundling.md}
42
42
  * Using vite's ?worker&url imports almost works (the paths are correct) but something about the transpiling breaks things I think.
43
+ *
43
44
  */
44
45
 
45
46
  export function useElectronLogger(
46
47
  pinoConfig?: PublicRuntimeConfig["logger"],
47
- windows?: () => BrowserWindow[], {
48
+ windows?: () => BrowserWindow[],
49
+ {
48
50
  receiveFromRenderer = true
49
- }: { receiveFromRenderer?: boolean } = {}
51
+ }: {
52
+ receiveFromRenderer?: boolean
53
+ } = {}
50
54
  ) {
51
55
  if (initiated && pinoConfig) {
52
56
  throw new Error("Config can only be passed the first time when initiating.")
@@ -6,11 +6,11 @@ export function wrapLoggerForElectron<T extends ReturnType<typeof useElectronLog
6
6
  logger: T,
7
7
  prefix: string = "main:"
8
8
  ): T {
9
- const res = {}
10
- for (const key of Object.keys(logger)) {
9
+ const res = {} as Record<keyof T, unknown>
10
+ for (const key of Object.keys(logger) as (keyof T)[]) {
11
11
  res[key] = (...args: any[]) => {
12
- logger[key]({ ...args[0], ns: prefix + args[0].ns }, ...args.slice(1))
12
+ (logger[key] as (...args: any[]) => void)({ ...args[0], ns: prefix + args[0].ns }, ...args.slice(1))
13
13
  }
14
14
  }
15
- return res
15
+ return res as T
16
16
  }
@@ -1,8 +1,7 @@
1
1
  import type { ipcRenderer as IpcRenderer } from "electron"
2
2
 
3
- import { ELECTRON_LOG_TYPE } from "./types.js"
4
-
5
- import type { Levels } from "../types.js"
3
+ import type { Levels } from "../../types.js"
4
+ import { ELECTRON_LOG_TYPE } from "../types.js"
6
5
 
7
6
  export type ElectronLoggerApi = {
8
7
  log: (level: Levels, data: any) => void
@@ -11,7 +10,13 @@ export type ElectronLoggerApi = {
11
10
 
12
11
  export function createElectronLoggerApi(ipcRenderer: typeof IpcRenderer): ElectronLoggerApi {
13
12
  return {
14
- log: (level: Levels, data: any) => ipcRenderer.send(ELECTRON_LOG_TYPE.TO_MAIN, { level, data }),
13
+ log: (level: Levels, data: any) => {
14
+ try {
15
+ ipcRenderer.send(ELECTRON_LOG_TYPE.TO_MAIN, { level, data })
16
+ } catch (error) {
17
+ throw new Error(`[nuxt-logger] could not forward a "${level}" log to electron's main process, its payload must be cloneable, pass raw values (e.g. \`toRaw\` on a reactive object). Log: ${JSON.stringify(data)}`, { cause: error })
18
+ }
19
+ },
15
20
  _logs: {
16
21
  on(cb: (level: Levels, data: any) => void) {
17
22
  ipcRenderer.on(ELECTRON_LOG_TYPE.FROM_MAIN_ON_RENDERER, (_event, level, data) => {
@@ -0,0 +1 @@
1
+ export { createElectronLoggerApi, type ElectronLoggerApi } from "./createElectronLoggerApi.js"
@@ -7,6 +7,8 @@ import type { PublicRuntimeConfig } from "@nuxt/schema"
7
7
  import type { LoggerOptions, TransportMultiOptions } from "pino"
8
8
  import { pino } from "pino"
9
9
 
10
+ import type { ElectronLoggerApi } from "../electron/preload/createElectronLoggerApi.js"
11
+
10
12
  // normally we would access logger.levels, but because we create
11
13
  // the shared config here we can't
12
14
  const levels = {
@@ -129,7 +131,7 @@ export function getBaseOptions(
129
131
  send: (level, logEvent) => {
130
132
  if (!logEvent.messages[0]?.ns?.startsWith("main") && levels.values[level] < levels.values[writeLevel]) {
131
133
  logEvent.messages[0].ns &&= `renderer:${logEvent.messages[0].ns}`
132
- ;(window as any).electron.api.log(logEvent)
134
+ ;((window as any).electron.api as ElectronLoggerApi).log(level, logEvent)
133
135
  }
134
136
  }
135
137
  }
@@ -1,3 +1,5 @@
1
+ import { toRaw } from "vue"
2
+
1
3
  import { defineNuxtPlugin, useRuntimeConfig } from "#imports"
2
4
 
3
5
  import { useLogger } from "../composables/useLogger"
@@ -7,7 +9,7 @@ export default defineNuxtPlugin({
7
9
  setup(nuxtApp) {
8
10
  if (import.meta.client) {
9
11
  nuxtApp.hook("app:created", () => {
10
- const config = useRuntimeConfig().public
12
+ const config = toRaw(useRuntimeConfig().public)
11
13
  const initialLog: any = { appInfo: config.appInfo }
12
14
  if (window.navigator !== undefined) {
13
15
  initialLog.environmentInfo = {
@@ -1,5 +1,5 @@
1
1
  import type { RuntimeConfig } from "nuxt/schema"
2
- import { type Logger, pino } from "pino"
2
+ import pino, { type Logger } from "pino"
3
3
 
4
4
  import { getBaseOptions } from "../helpers/getBaseOptions.js"
5
5
  import type { BaseLogger, Levels } from "../types.js"
@@ -38,7 +38,17 @@ export function createUseLogger(
38
38
  const { opts, transports, browserOpts, debug } = getBaseOptions(config.logger, serverPathResolver)
39
39
  let transport: any
40
40
  if (import.meta.server) {
41
- transport = pino.transport(transports)
41
+ try {
42
+ transport = pino.transport(transports)
43
+ } catch (e) {
44
+ const missingTarget = /unable to determine transport target for "([^"]+)"/.exec((e as Error)?.message ?? "")?.[1]
45
+ if (import.meta.dev && missingTarget === "pino-pretty") {
46
+ console.warn(`[nuxt-logger] "pino-pretty" could not be resolved, pretty console logs are disabled. Add "pino-pretty" to your app dependencies or set disabledServerTransportTargets: ["pino-pretty"].`)
47
+ transport = pino.transport({ targets: transports.targets.filter(t => (t as any).target !== "pino-pretty") })
48
+ } else {
49
+ throw e
50
+ }
51
+ }
42
52
  }
43
53
  const pinoLogger = pino(
44
54
  {
@@ -1,13 +0,0 @@
1
- import { ELECTRON_LOG_TYPE } from "./types.js";
2
- export function createElectronLoggerApi(ipcRenderer) {
3
- return {
4
- log: (level, data) => ipcRenderer.send(ELECTRON_LOG_TYPE.TO_MAIN, { level, data }),
5
- _logs: {
6
- on(cb) {
7
- ipcRenderer.on(ELECTRON_LOG_TYPE.FROM_MAIN_ON_RENDERER, (_event, level, data) => {
8
- cb(level, data);
9
- });
10
- }
11
- }
12
- };
13
- }