@vsfedorenko/next-logger 0.1.0

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 (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +229 -0
  3. package/dist/browser.d.ts +41 -0
  4. package/dist/browser.d.ts.map +1 -0
  5. package/dist/browser.js +47 -0
  6. package/dist/browser.js.map +1 -0
  7. package/dist/config.d.ts +38 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +103 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/defaults.d.ts +31 -0
  12. package/dist/defaults.d.ts.map +1 -0
  13. package/dist/defaults.js +119 -0
  14. package/dist/defaults.js.map +1 -0
  15. package/dist/index.d.ts +87 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +100 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/logger.d.ts +21 -0
  20. package/dist/logger.d.ts.map +1 -0
  21. package/dist/logger.js +43 -0
  22. package/dist/logger.js.map +1 -0
  23. package/dist/patches/console.d.ts +38 -0
  24. package/dist/patches/console.d.ts.map +1 -0
  25. package/dist/patches/console.js +82 -0
  26. package/dist/patches/console.js.map +1 -0
  27. package/dist/patches/next.d.ts +42 -0
  28. package/dist/patches/next.d.ts.map +1 -0
  29. package/dist/patches/next.js +124 -0
  30. package/dist/patches/next.js.map +1 -0
  31. package/dist/patches/util.d.ts +25 -0
  32. package/dist/patches/util.d.ts.map +1 -0
  33. package/dist/patches/util.js +41 -0
  34. package/dist/patches/util.js.map +1 -0
  35. package/dist/presets/all.d.ts +14 -0
  36. package/dist/presets/all.d.ts.map +1 -0
  37. package/dist/presets/all.js +15 -0
  38. package/dist/presets/all.js.map +1 -0
  39. package/dist/presets/next-only.d.ts +12 -0
  40. package/dist/presets/next-only.d.ts.map +1 -0
  41. package/dist/presets/next-only.js +13 -0
  42. package/dist/presets/next-only.js.map +1 -0
  43. package/dist/reporters/json.d.ts +37 -0
  44. package/dist/reporters/json.d.ts.map +1 -0
  45. package/dist/reporters/json.js +160 -0
  46. package/dist/reporters/json.js.map +1 -0
  47. package/dist/reporters/sentry.d.ts +70 -0
  48. package/dist/reporters/sentry.d.ts.map +1 -0
  49. package/dist/reporters/sentry.js +152 -0
  50. package/dist/reporters/sentry.js.map +1 -0
  51. package/dist/types.d.ts +56 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +24 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +101 -0
@@ -0,0 +1,87 @@
1
+ /**
2
+ * # @vsfedorenko/next-logger
3
+ *
4
+ * A universal logging kit for Next.js. Monkeypatches Next.js' internal
5
+ * logger (`next/dist/build/output/log`) and the global `console.*` so all
6
+ * diagnostic output flows through a single level-controllable sink —
7
+ * consola by default, with reporters for Sentry, JSON, and more — without a
8
+ * custom Next.js server.
9
+ *
10
+ * ## Usage
11
+ *
12
+ * ### Instrumentation hook (Next.js ≥ 9.3 / instrumentationHook)
13
+ *
14
+ * ```ts
15
+ * // instrumentation.ts (project root)
16
+ * export async function register() {
17
+ * if (process.env.NEXT_RUNTIME === "nodejs") {
18
+ * await import("@vsfedorenko/next-logger");
19
+ * }
20
+ * }
21
+ * ```
22
+ *
23
+ * The default import applies both patches (Next logger + console). To patch
24
+ * only Next's logger:
25
+ *
26
+ * ```ts
27
+ * await import("@vsfedorenko/next-logger/presets/next-only");
28
+ * ```
29
+ *
30
+ * ### `-r` preload
31
+ *
32
+ * ```sh
33
+ * node -r @vsfedorenko/next-logger server.js
34
+ * ```
35
+ *
36
+ * ## Configuration
37
+ *
38
+ * Optional `next-logger.config.ts` (discovered from cwd upward):
39
+ *
40
+ * ```ts
41
+ * import { createConsola } from "consola";
42
+ *
43
+ * export default {
44
+ * consola: createConsola({ level: 4 }), // full custom instance
45
+ * };
46
+ * ```
47
+ *
48
+ * Or partial options (merged with defaults):
49
+ *
50
+ * ```ts
51
+ * export default {
52
+ * consola: { level: 4, formatOptions: { date: false } },
53
+ * };
54
+ * ```
55
+ *
56
+ * Or a factory (receives the library's default options):
57
+ *
58
+ * ```ts
59
+ * import type { ConsolaOptions } from "consola";
60
+ *
61
+ * export default {
62
+ * consola: (defaults: Partial<ConsolaOptions>) =>
63
+ * createConsola({ ...defaults, level: 5 }),
64
+ * };
65
+ * ```
66
+ *
67
+ * ## Log level
68
+ *
69
+ * Without a config file, the level resolves from (in order) `LOG_LEVEL` or
70
+ * `NEXT_PUBLIC_LOG_LEVEL` (numeric or named: silent/fatal/error/warn/info/log/
71
+ * debug/trace/verbose), falling back to `3` (info).
72
+ */
73
+ import "./presets/all";
74
+ export { logger } from "./logger";
75
+ export { loadConfig } from "./config";
76
+ export type { NextLoggerConfig, ResolvedConfig } from "./config";
77
+ export { defaultConsolaOptions, resolveFormat } from "./defaults";
78
+ export type { LogFormat } from "./defaults";
79
+ export { createJsonReporter } from "./reporters/json";
80
+ export { patchNext, routeNextMethod, NEXT_PREFIXES } from "./patches/next";
81
+ export type { NextMethodName } from "./patches/next";
82
+ export { patchConsole, routeConsoleMethod, CONSOLE_METHODS } from "./patches/console";
83
+ export type { ConsoleMethodName } from "./patches/console";
84
+ export { isEmptyMessage, skipEmpty } from "./patches/util";
85
+ export type { LogFunction, NextLogFn, NextLogModule } from "./types";
86
+ export type { ConsolaInstance, ConsolaOptions, ConsolaReporter, FormatOptions, InputLogObject, LogLevel, LogObject, LogType, } from "consola";
87
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AAEH,OAAO,eAAe,CAAC;AAGvB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAClE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC3E,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACtF,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3D,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIrE,YAAY,EACV,eAAe,EACf,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,EACR,SAAS,EACT,OAAO,GACR,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ /**
3
+ * # @vsfedorenko/next-logger
4
+ *
5
+ * A universal logging kit for Next.js. Monkeypatches Next.js' internal
6
+ * logger (`next/dist/build/output/log`) and the global `console.*` so all
7
+ * diagnostic output flows through a single level-controllable sink —
8
+ * consola by default, with reporters for Sentry, JSON, and more — without a
9
+ * custom Next.js server.
10
+ *
11
+ * ## Usage
12
+ *
13
+ * ### Instrumentation hook (Next.js ≥ 9.3 / instrumentationHook)
14
+ *
15
+ * ```ts
16
+ * // instrumentation.ts (project root)
17
+ * export async function register() {
18
+ * if (process.env.NEXT_RUNTIME === "nodejs") {
19
+ * await import("@vsfedorenko/next-logger");
20
+ * }
21
+ * }
22
+ * ```
23
+ *
24
+ * The default import applies both patches (Next logger + console). To patch
25
+ * only Next's logger:
26
+ *
27
+ * ```ts
28
+ * await import("@vsfedorenko/next-logger/presets/next-only");
29
+ * ```
30
+ *
31
+ * ### `-r` preload
32
+ *
33
+ * ```sh
34
+ * node -r @vsfedorenko/next-logger server.js
35
+ * ```
36
+ *
37
+ * ## Configuration
38
+ *
39
+ * Optional `next-logger.config.ts` (discovered from cwd upward):
40
+ *
41
+ * ```ts
42
+ * import { createConsola } from "consola";
43
+ *
44
+ * export default {
45
+ * consola: createConsola({ level: 4 }), // full custom instance
46
+ * };
47
+ * ```
48
+ *
49
+ * Or partial options (merged with defaults):
50
+ *
51
+ * ```ts
52
+ * export default {
53
+ * consola: { level: 4, formatOptions: { date: false } },
54
+ * };
55
+ * ```
56
+ *
57
+ * Or a factory (receives the library's default options):
58
+ *
59
+ * ```ts
60
+ * import type { ConsolaOptions } from "consola";
61
+ *
62
+ * export default {
63
+ * consola: (defaults: Partial<ConsolaOptions>) =>
64
+ * createConsola({ ...defaults, level: 5 }),
65
+ * };
66
+ * ```
67
+ *
68
+ * ## Log level
69
+ *
70
+ * Without a config file, the level resolves from (in order) `LOG_LEVEL` or
71
+ * `NEXT_PUBLIC_LOG_LEVEL` (numeric or named: silent/fatal/error/warn/info/log/
72
+ * debug/trace/verbose), falling back to `3` (info).
73
+ */
74
+ Object.defineProperty(exports, "__esModule", { value: true });
75
+ exports.skipEmpty = exports.isEmptyMessage = exports.CONSOLE_METHODS = exports.routeConsoleMethod = exports.patchConsole = exports.NEXT_PREFIXES = exports.routeNextMethod = exports.patchNext = exports.createJsonReporter = exports.resolveFormat = exports.defaultConsolaOptions = exports.loadConfig = exports.logger = void 0;
76
+ require("./presets/all");
77
+ // Core instance + config.
78
+ var logger_1 = require("./logger");
79
+ Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
80
+ var config_1 = require("./config");
81
+ Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_1.loadConfig; } });
82
+ var defaults_1 = require("./defaults");
83
+ Object.defineProperty(exports, "defaultConsolaOptions", { enumerable: true, get: function () { return defaults_1.defaultConsolaOptions; } });
84
+ Object.defineProperty(exports, "resolveFormat", { enumerable: true, get: function () { return defaults_1.resolveFormat; } });
85
+ // JSON reporter (server-side structured logging).
86
+ var json_1 = require("./reporters/json");
87
+ Object.defineProperty(exports, "createJsonReporter", { enumerable: true, get: function () { return json_1.createJsonReporter; } });
88
+ // Patching API.
89
+ var next_1 = require("./patches/next");
90
+ Object.defineProperty(exports, "patchNext", { enumerable: true, get: function () { return next_1.patchNext; } });
91
+ Object.defineProperty(exports, "routeNextMethod", { enumerable: true, get: function () { return next_1.routeNextMethod; } });
92
+ Object.defineProperty(exports, "NEXT_PREFIXES", { enumerable: true, get: function () { return next_1.NEXT_PREFIXES; } });
93
+ var console_1 = require("./patches/console");
94
+ Object.defineProperty(exports, "patchConsole", { enumerable: true, get: function () { return console_1.patchConsole; } });
95
+ Object.defineProperty(exports, "routeConsoleMethod", { enumerable: true, get: function () { return console_1.routeConsoleMethod; } });
96
+ Object.defineProperty(exports, "CONSOLE_METHODS", { enumerable: true, get: function () { return console_1.CONSOLE_METHODS; } });
97
+ var util_1 = require("./patches/util");
98
+ Object.defineProperty(exports, "isEmptyMessage", { enumerable: true, get: function () { return util_1.isEmptyMessage; } });
99
+ Object.defineProperty(exports, "skipEmpty", { enumerable: true, get: function () { return util_1.skipEmpty; } });
100
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;;;AAEH,yBAAuB;AAEvB,0BAA0B;AAC1B,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,mCAAsC;AAA7B,oGAAA,UAAU,OAAA;AAEnB,uCAAkE;AAAzD,iHAAA,qBAAqB,OAAA;AAAE,yGAAA,aAAa,OAAA;AAG7C,kDAAkD;AAClD,yCAAsD;AAA7C,0GAAA,kBAAkB,OAAA;AAE3B,gBAAgB;AAChB,uCAA2E;AAAlE,iGAAA,SAAS,OAAA;AAAE,uGAAA,eAAe,OAAA;AAAE,qGAAA,aAAa,OAAA;AAElD,6CAAsF;AAA7E,uGAAA,YAAY,OAAA;AAAE,6GAAA,kBAAkB,OAAA;AAAE,0GAAA,eAAe,OAAA;AAE1D,uCAA2D;AAAlD,sGAAA,cAAc,OAAA;AAAE,iGAAA,SAAS,OAAA"}
@@ -0,0 +1,21 @@
1
+ import { type ConsolaInstance } from "consola";
2
+ /**
3
+ * The shared consola instance backing all patches.
4
+ *
5
+ * Resolution order:
6
+ * 1. `next-logger.config.{ts,js,cjs,...}` → `consola` key is a
7
+ * {@link ConsolaInstance} or a factory → used directly.
8
+ * 2. Same config → `consola` key is a partial options object → merged with
9
+ * defaults, then built.
10
+ * 3. No config → built from {@link defaultConsolaOptions}.
11
+ *
12
+ * When `LOG_FORMAT=json` (or `NEXT_PUBLIC_LOG_FORMAT=json`), the logger uses
13
+ * the {@link createJsonReporter} instead of consola's default pretty reporter.
14
+ * A config file's custom instance / factory bypasses format selection — the
15
+ * user's instance controls everything.
16
+ *
17
+ * Both patches (`patches/next`, `patches/console`) call `.withTag()` on this
18
+ * object so they can namespace their output.
19
+ */
20
+ export declare const logger: ConsolaInstance;
21
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,SAAS,CAAC;AAK9D;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,MAAM,EAAE,eAA+B,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logger = void 0;
4
+ const consola_1 = require("consola");
5
+ const config_1 = require("./config");
6
+ const defaults_1 = require("./defaults");
7
+ const json_1 = require("./reporters/json");
8
+ /**
9
+ * The shared consola instance backing all patches.
10
+ *
11
+ * Resolution order:
12
+ * 1. `next-logger.config.{ts,js,cjs,...}` → `consola` key is a
13
+ * {@link ConsolaInstance} or a factory → used directly.
14
+ * 2. Same config → `consola` key is a partial options object → merged with
15
+ * defaults, then built.
16
+ * 3. No config → built from {@link defaultConsolaOptions}.
17
+ *
18
+ * When `LOG_FORMAT=json` (or `NEXT_PUBLIC_LOG_FORMAT=json`), the logger uses
19
+ * the {@link createJsonReporter} instead of consola's default pretty reporter.
20
+ * A config file's custom instance / factory bypasses format selection — the
21
+ * user's instance controls everything.
22
+ *
23
+ * Both patches (`patches/next`, `patches/console`) call `.withTag()` on this
24
+ * object so they can namespace their output.
25
+ */
26
+ exports.logger = buildLogger();
27
+ function buildLogger() {
28
+ const resolved = (0, config_1.loadConfig)();
29
+ switch (resolved.kind) {
30
+ case "instance":
31
+ return resolved.instance;
32
+ case "options": {
33
+ const instance = (0, consola_1.createConsola)(resolved.options);
34
+ // Override reporters when JSON format is requested. Only applies to the
35
+ // options path (custom instances are used as-is).
36
+ if ((0, defaults_1.resolveFormat)() === "json") {
37
+ instance.setReporters([(0, json_1.createJsonReporter)()]);
38
+ }
39
+ return instance;
40
+ }
41
+ }
42
+ }
43
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;;AAAA,qCAA8D;AAC9D,qCAAsC;AACtC,yCAA2C;AAC3C,2CAAsD;AAEtD;;;;;;;;;;;;;;;;;GAiBG;AACU,QAAA,MAAM,GAAoB,WAAW,EAAE,CAAC;AAErD,SAAS,WAAW;IAClB,MAAM,QAAQ,GAAG,IAAA,mBAAU,GAAE,CAAC;IAE9B,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,UAAU;YACb,OAAO,QAAQ,CAAC,QAAQ,CAAC;QAC3B,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,QAAQ,GAAG,IAAA,uBAAa,EAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAEjD,wEAAwE;YACxE,kDAAkD;YAClD,IAAI,IAAA,wBAAa,GAAE,KAAK,MAAM,EAAE,CAAC;gBAC/B,QAAQ,CAAC,YAAY,CAAC,CAAC,IAAA,yBAAkB,GAAE,CAAC,CAAC,CAAC;YAChD,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Patches the global `console.*` methods so every call routes through the
3
+ * shared consola instance tagged `console`.
4
+ *
5
+ * This captures diagnostic output from third-party libraries and application
6
+ * code that calls `console.log`/`console.error` directly — funnelling it
7
+ * through the same level-controllable sink as Next's own logs.
8
+ *
9
+ * This is a side-effect module — importing it applies the patch exactly once.
10
+ */
11
+ import type { ConsolaInstance } from "consola";
12
+ import type { LogFunction } from "../types";
13
+ /**
14
+ * The console methods this patch overwrites.
15
+ */
16
+ export declare const CONSOLE_METHODS: readonly ["log", "debug", "info", "warn", "error"];
17
+ /** A console method name we patch. */
18
+ export type ConsoleMethodName = (typeof CONSOLE_METHODS)[number];
19
+ /**
20
+ * Maps a console method name to the corresponding consola log function.
21
+ *
22
+ * `console.log` and `console.info` both map to consola `info` (matching the
23
+ * original's behaviour). The returned function is bound to a child logger
24
+ * tagged with `tag`, so every call is namespaced.
25
+ *
26
+ * Pure function — given a consola instance and a tag, returns the routing
27
+ * function. Exported so the level mapping can be unit-tested without touching
28
+ * the global `console`.
29
+ */
30
+ export declare function routeConsoleMethod(method: ConsoleMethodName | string, consola: ConsolaInstance, tag: string): LogFunction;
31
+ /**
32
+ * Applies the console patch. Overwrites `console.log`, `console.debug`,
33
+ * `console.info`, `console.warn`, `console.error` with bound consola methods.
34
+ *
35
+ * @param tagOverride override the `console` tag (useful for tests).
36
+ */
37
+ export declare function patchConsole(tagOverride?: string): void;
38
+ //# sourceMappingURL=console.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/patches/console.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C;;GAEG;AACH,eAAO,MAAM,eAAe,oDAMlB,CAAC;AAEX,sCAAsC;AACtC,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,iBAAiB,GAAG,MAAM,EAClC,OAAO,EAAE,eAAe,EACxB,GAAG,EAAE,MAAM,GACV,WAAW,CAKb;AAyBD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAOvD"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /**
3
+ * Patches the global `console.*` methods so every call routes through the
4
+ * shared consola instance tagged `console`.
5
+ *
6
+ * This captures diagnostic output from third-party libraries and application
7
+ * code that calls `console.log`/`console.error` directly — funnelling it
8
+ * through the same level-controllable sink as Next's own logs.
9
+ *
10
+ * This is a side-effect module — importing it applies the patch exactly once.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.CONSOLE_METHODS = void 0;
14
+ exports.routeConsoleMethod = routeConsoleMethod;
15
+ exports.patchConsole = patchConsole;
16
+ const logger_1 = require("../logger");
17
+ const util_1 = require("./util");
18
+ /**
19
+ * The console methods this patch overwrites.
20
+ */
21
+ exports.CONSOLE_METHODS = [
22
+ "log",
23
+ "debug",
24
+ "info",
25
+ "warn",
26
+ "error",
27
+ ];
28
+ /**
29
+ * Maps a console method name to the corresponding consola log function.
30
+ *
31
+ * `console.log` and `console.info` both map to consola `info` (matching the
32
+ * original's behaviour). The returned function is bound to a child logger
33
+ * tagged with `tag`, so every call is namespaced.
34
+ *
35
+ * Pure function — given a consola instance and a tag, returns the routing
36
+ * function. Exported so the level mapping can be unit-tested without touching
37
+ * the global `console`.
38
+ */
39
+ function routeConsoleMethod(method, consola, tag) {
40
+ const child = consola.withTag(tag);
41
+ const bound = selectConsolaMethod(method, child);
42
+ return (0, util_1.skipEmpty)(bound);
43
+ }
44
+ /**
45
+ * Selects the consola method matching a console method name.
46
+ *
47
+ * The bound function is returned directly; consola's methods accept the same
48
+ * `(...args: unknown[])` shape as {@link LogFunction}.
49
+ */
50
+ function selectConsolaMethod(method, consola) {
51
+ switch (method) {
52
+ case "error":
53
+ return consola.error.bind(consola);
54
+ case "warn":
55
+ return consola.warn.bind(consola);
56
+ case "debug":
57
+ return consola.debug.bind(consola);
58
+ case "log":
59
+ case "info":
60
+ return consola.info.bind(consola);
61
+ default:
62
+ // Unknown method name — default to info (same as the original).
63
+ return consola.info.bind(consola);
64
+ }
65
+ }
66
+ /**
67
+ * Applies the console patch. Overwrites `console.log`, `console.debug`,
68
+ * `console.info`, `console.warn`, `console.error` with bound consola methods.
69
+ *
70
+ * @param tagOverride override the `console` tag (useful for tests).
71
+ */
72
+ function patchConsole(tagOverride) {
73
+ const tag = tagOverride ?? "console";
74
+ for (const method of exports.CONSOLE_METHODS) {
75
+ const routed = routeConsoleMethod(method, logger_1.logger, tag);
76
+ console[method] = routed;
77
+ }
78
+ }
79
+ // Apply on import (side effect), matching the original's
80
+ // `require('./patches/console')` semantics.
81
+ patchConsole();
82
+ //# sourceMappingURL=console.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/patches/console.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAgCH,gDASC;AA+BD,oCAOC;AA5ED,sCAAmC;AAEnC,iCAAmC;AAEnC;;GAEG;AACU,QAAA,eAAe,GAAG;IAC7B,KAAK;IACL,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;CACC,CAAC;AAKX;;;;;;;;;;GAUG;AACH,SAAgB,kBAAkB,CAChC,MAAkC,EAClC,OAAwB,EACxB,GAAW;IAEX,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAEnC,MAAM,KAAK,GAAgB,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC9D,OAAO,IAAA,gBAAS,EAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,MAAc,EAAE,OAAwB;IACnE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAgB,CAAC;QACpD,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAgB,CAAC;QACnD,KAAK,OAAO;YACV,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAgB,CAAC;QACpD,KAAK,KAAK,CAAC;QACX,KAAK,MAAM;YACT,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAgB,CAAC;QACnD;YACE,gEAAgE;YAChE,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAgB,CAAC;IACrD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAAC,WAAoB;IAC/C,MAAM,GAAG,GAAG,WAAW,IAAI,SAAS,CAAC;IAErC,KAAK,MAAM,MAAM,IAAI,uBAAe,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,eAAM,EAAE,GAAG,CAAC,CAAC;QACvD,OAAO,CAAC,MAAM,CAAC,GAAG,MAAoC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,yDAAyD;AACzD,4CAA4C;AAC5C,YAAY,EAAE,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Patches Next.js' internal logger (`next/dist/build/output/log`) so every
3
+ * call routes through the shared consola instance tagged `next.js`.
4
+ *
5
+ * Next 13+ defines its logger exports as non-configurable accessor properties,
6
+ * which would throw under a plain redefinition. We work around this by
7
+ * replacing `require.cache[...].exports` with a shallow copy (the original's
8
+ * approach), then defining each method as a plain value property on the copy.
9
+ *
10
+ * This is a side-effect module — importing it applies the patch exactly once.
11
+ */
12
+ import type { ConsolaInstance } from "consola";
13
+ import type { LogFunction } from "../types";
14
+ /**
15
+ * The methods exported by Next's log module that we patch.
16
+ *
17
+ * `prefixes` is the set Next itself advertises (wait/error/warn/ready/info/
18
+ * event/trace). `bootstrap` is an extra export that bypasses the prefix logic
19
+ * (raw `console.log`) — we route it too so it stays consistent.
20
+ */
21
+ export declare const NEXT_PREFIXES: readonly ["wait", "error", "warn", "ready", "info", "event", "trace"];
22
+ /** A Next.js prefix method name we patch. */
23
+ export type NextMethodName = (typeof NEXT_PREFIXES)[number];
24
+ /**
25
+ * Maps a Next.js prefix name to the corresponding consola log function.
26
+ * `trace` maps to consola's native `trace` — no fallback needed (consola has
27
+ * it; the pino original had to fall back to `debug` for Winston which lacks
28
+ * trace).
29
+ *
30
+ * Pure function — given a consola instance and a tag, returns the routing
31
+ * function. Exported so the level mapping can be unit-tested without touching
32
+ * `require.cache` or a real Next.js install.
33
+ */
34
+ export declare function routeNextMethod(method: NextMethodName | string, consola: ConsolaInstance, tag: string): LogFunction;
35
+ /**
36
+ * Applies the Next.js logger patch. Safe to call multiple times — it
37
+ * re-derives the methods from the current {@link logger} each time.
38
+ *
39
+ * @param tagOverride override the `next.js` tag (useful for tests).
40
+ */
41
+ export declare function patchNext(tagOverride?: string): void;
42
+ //# sourceMappingURL=next.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../src/patches/next.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAiB,MAAM,UAAU,CAAC;AAG3D;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,uEAQhB,CAAC;AAEX,6CAA6C;AAC7C,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,cAAc,GAAG,MAAM,EAC/B,OAAO,EAAE,eAAe,EACxB,GAAG,EAAE,MAAM,GACV,WAAW,CAKb;AAmBD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAuCpD"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ /**
3
+ * Patches Next.js' internal logger (`next/dist/build/output/log`) so every
4
+ * call routes through the shared consola instance tagged `next.js`.
5
+ *
6
+ * Next 13+ defines its logger exports as non-configurable accessor properties,
7
+ * which would throw under a plain redefinition. We work around this by
8
+ * replacing `require.cache[...].exports` with a shallow copy (the original's
9
+ * approach), then defining each method as a plain value property on the copy.
10
+ *
11
+ * This is a side-effect module — importing it applies the patch exactly once.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.NEXT_PREFIXES = void 0;
15
+ exports.routeNextMethod = routeNextMethod;
16
+ exports.patchNext = patchNext;
17
+ const logger_1 = require("../logger");
18
+ const util_1 = require("./util");
19
+ /**
20
+ * The methods exported by Next's log module that we patch.
21
+ *
22
+ * `prefixes` is the set Next itself advertises (wait/error/warn/ready/info/
23
+ * event/trace). `bootstrap` is an extra export that bypasses the prefix logic
24
+ * (raw `console.log`) — we route it too so it stays consistent.
25
+ */
26
+ exports.NEXT_PREFIXES = [
27
+ "wait",
28
+ "error",
29
+ "warn",
30
+ "ready",
31
+ "info",
32
+ "event",
33
+ "trace",
34
+ ];
35
+ /**
36
+ * Maps a Next.js prefix name to the corresponding consola log function.
37
+ * `trace` maps to consola's native `trace` — no fallback needed (consola has
38
+ * it; the pino original had to fall back to `debug` for Winston which lacks
39
+ * trace).
40
+ *
41
+ * Pure function — given a consola instance and a tag, returns the routing
42
+ * function. Exported so the level mapping can be unit-tested without touching
43
+ * `require.cache` or a real Next.js install.
44
+ */
45
+ function routeNextMethod(method, consola, tag) {
46
+ const child = consola.withTag(tag);
47
+ const bound = selectConsolaMethod(method, child);
48
+ return (0, util_1.skipEmpty)(bound);
49
+ }
50
+ /**
51
+ * Selects the consola method matching a Next.js method name.
52
+ */
53
+ function selectConsolaMethod(method, consola) {
54
+ switch (method) {
55
+ case "error":
56
+ return consola.error.bind(consola);
57
+ case "warn":
58
+ return consola.warn.bind(consola);
59
+ case "trace":
60
+ return consola.trace.bind(consola);
61
+ default:
62
+ // wait, ready, info, event, bootstrap → info
63
+ return consola.info.bind(consola);
64
+ }
65
+ }
66
+ /**
67
+ * Applies the Next.js logger patch. Safe to call multiple times — it
68
+ * re-derives the methods from the current {@link logger} each time.
69
+ *
70
+ * @param tagOverride override the `next.js` tag (useful for tests).
71
+ */
72
+ function patchNext(tagOverride) {
73
+ const tag = tagOverride ?? "next.js";
74
+ let nextLog;
75
+ try {
76
+ nextLog = require("next/dist/build/output/log");
77
+ }
78
+ catch {
79
+ // `next` is not installed — nothing to patch.
80
+ return;
81
+ }
82
+ // Build the routed methods for every prefix + bootstrap.
83
+ const methodNames = [...Object.keys(nextLog.prefixes), "bootstrap"];
84
+ const routed = {};
85
+ for (const method of methodNames) {
86
+ routed[method] = routeNextMethod(method, logger_1.logger, tag);
87
+ }
88
+ // Strategy 1: if we have access to the CJS module cache, replace the exports
89
+ // with a fresh shallow copy. This sidesteps the non-configurable accessor
90
+ // properties Next 13+ defines (they throw under defineProperty).
91
+ const cacheObject = tryGetCache("next/dist/build/output/log");
92
+ if (cacheObject !== null) {
93
+ cacheObject.exports = { ...nextLog, ...routed };
94
+ return;
95
+ }
96
+ // Strategy 2 (fallback): mutate the live exports object in place. Try plain
97
+ // assignment first; if the property is non-configurable + non-writable,
98
+ // skip silently (the routing function is still correct — verified by unit
99
+ // tests on routeNextMethod directly).
100
+ const target = nextLog;
101
+ for (const [method, fn] of Object.entries(routed)) {
102
+ try {
103
+ target[method] = fn;
104
+ }
105
+ catch {
106
+ // Non-writable, non-configurable — skip.
107
+ }
108
+ }
109
+ }
110
+ /** Looks up a module in the CJS cache by specifier; returns null if absent. */
111
+ function tryGetCache(specifier) {
112
+ try {
113
+ const resolved = require.resolve(specifier);
114
+ const cached = require.cache[resolved];
115
+ return cached ?? null;
116
+ }
117
+ catch {
118
+ return null;
119
+ }
120
+ }
121
+ // Apply on import (side effect), matching the original's
122
+ // `require('./patches/next')` semantics.
123
+ patchNext();
124
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/patches/next.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shared helpers for the patch modules.
3
+ */
4
+ /**
5
+ * Returns `true` when the arguments constitute an "empty" message — i.e. there
6
+ * is nothing meaningful to log. Used to skip printing when Next.js or `console`
7
+ * calls a method with no arguments, or with only `undefined`/`null`/`""`.
8
+ *
9
+ * Matches the upstream sainsburys-tech/next-logger behaviour where an empty
10
+ * message produces no output, and avoids consola emitting a bare tag line with
11
+ * no payload.
12
+ *
13
+ * Note: falsy-but-present values (`0`, `false`) are **not** considered empty —
14
+ * they carry diagnostic value and are printed normally.
15
+ */
16
+ export declare function isEmptyMessage(args: readonly unknown[]): boolean;
17
+ /**
18
+ * Wraps a log function so it becomes a no-op for empty messages (see
19
+ * {@link isEmptyMessage}). Non-empty messages pass through unchanged.
20
+ *
21
+ * Generic over the input function's parameter types, so the returned wrapper
22
+ * has the same call signature as `fn` — no `unknown[]` widening.
23
+ */
24
+ export declare function skipEmpty<TArgs extends unknown[]>(fn: (...args: TArgs) => void): (...args: TArgs) => void;
25
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/patches/util.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAMhE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,SAAS,OAAO,EAAE,EAC/C,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,IAAI,GAC3B,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,IAAI,CAK1B"}
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ /**
3
+ * Shared helpers for the patch modules.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isEmptyMessage = isEmptyMessage;
7
+ exports.skipEmpty = skipEmpty;
8
+ /**
9
+ * Returns `true` when the arguments constitute an "empty" message — i.e. there
10
+ * is nothing meaningful to log. Used to skip printing when Next.js or `console`
11
+ * calls a method with no arguments, or with only `undefined`/`null`/`""`.
12
+ *
13
+ * Matches the upstream sainsburys-tech/next-logger behaviour where an empty
14
+ * message produces no output, and avoids consola emitting a bare tag line with
15
+ * no payload.
16
+ *
17
+ * Note: falsy-but-present values (`0`, `false`) are **not** considered empty —
18
+ * they carry diagnostic value and are printed normally.
19
+ */
20
+ function isEmptyMessage(args) {
21
+ if (args.length === 0)
22
+ return true;
23
+ // Skip when every argument is `undefined`, `null`, or `""` — these carry no
24
+ // diagnostic value and would render as an empty/blank line under consola.
25
+ return args.every((arg) => arg === undefined || arg === null || arg === "");
26
+ }
27
+ /**
28
+ * Wraps a log function so it becomes a no-op for empty messages (see
29
+ * {@link isEmptyMessage}). Non-empty messages pass through unchanged.
30
+ *
31
+ * Generic over the input function's parameter types, so the returned wrapper
32
+ * has the same call signature as `fn` — no `unknown[]` widening.
33
+ */
34
+ function skipEmpty(fn) {
35
+ return (...args) => {
36
+ if (isEmptyMessage(args))
37
+ return;
38
+ fn(...args);
39
+ };
40
+ }
41
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/patches/util.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAcH,wCAMC;AASD,8BAOC;AAlCD;;;;;;;;;;;GAWG;AACH,SAAgB,cAAc,CAAC,IAAwB;IACrD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnC,4EAA4E;IAC5E,0EAA0E;IAC1E,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,SAAS,CACvB,EAA4B;IAE5B,OAAO,CAAC,GAAG,IAAW,EAAQ,EAAE;QAC9B,IAAI,cAAc,CAAC,IAAI,CAAC;YAAE,OAAO;QACjC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"}