@velajs/vela 0.8.0 → 0.9.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.
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ export type { Type, Token, InjectableOptions, ProviderOptions, } from './contain
9
9
  export { METADATA_KEYS, HttpMethod, ParamType, Scope } from './constants';
10
10
  export { Controller, Version, Get, Post, Put, Patch, Delete, Options, Head, All, Sse, Param, Query, Body, Headers, Req, Res, Ip, Cookie, Cookies, RawBody, HttpCode, Header, Redirect, createParamDecorator, applyDecorators, } from './http/index';
11
11
  export { Logger, LogLevel } from './services/index';
12
- export type { LoggerService } from './services/index';
12
+ export type { LoggerService, ContextProvider, Writer, LoggerLevelName } from './services/index';
13
13
  export { ConfigModule, ConfigService, CONFIG_OPTIONS } from './config/index';
14
14
  export type { ConfigModuleOptions } from './config/index';
15
15
  export { HttpModule, HttpService, HTTP_MODULE_OPTIONS, HttpRequestException } from './fetch/index';
@@ -1,2 +1,2 @@
1
1
  export { Logger, LogLevel } from './logger';
2
- export type { LoggerService } from './logger';
2
+ export type { LoggerService, ContextProvider, Writer, LoggerLevelName } from './logger';
@@ -13,18 +13,46 @@ export interface LoggerService {
13
13
  debug?(message: unknown, ...optionalParams: unknown[]): void;
14
14
  verbose?(message: unknown, ...optionalParams: unknown[]): void;
15
15
  }
16
+ export type ContextProvider = () => Record<string, unknown>;
17
+ export type LoggerLevelName = 'LOG' | 'ERROR' | 'WARN' | 'DEBUG' | 'VERBOSE';
18
+ export type Writer = (level: LoggerLevelName, line: string, ...rest: unknown[]) => void;
16
19
  export declare class Logger implements LoggerService {
17
20
  static level: LogLevel;
18
21
  private static globalLogger;
22
+ private static globalContextProviders;
23
+ private static globalWriter;
19
24
  private context?;
25
+ private instanceContextProviders;
26
+ private instanceWriter?;
20
27
  static setLogLevel(level: LogLevel): void;
21
28
  static overrideLogger(logger: LoggerService | false): void;
29
+ /** Register a context provider run on every log line from every logger. */
30
+ static addContextProvider(provider: ContextProvider): void;
31
+ /** Remove all registered global context providers. */
32
+ static clearContextProviders(): void;
33
+ /** Replace the default console writer. Useful on edge runtimes that have
34
+ * a different output sink (e.g. `env.LOGS.writeDataPoint` on Workers). */
35
+ static setWriter(writer: Writer): void;
36
+ /** Restore the default console-based writer. */
37
+ static resetWriter(): void;
22
38
  constructor(context?: string);
23
39
  setContext(context: string): void;
40
+ /** Add a context provider that runs only for THIS logger instance.
41
+ * Children created via extend() inherit these providers by copy. */
42
+ addContextProvider(provider: ContextProvider): this;
43
+ /** Override the writer for this logger (and any extend() children). */
44
+ setWriter(writer: Writer): this;
45
+ /** Create a child logger with a nested namespace. Context becomes
46
+ * `parent:child`; instance-level providers and writers are inherited
47
+ * by copy so later mutations on either logger stay isolated. */
48
+ extend(namespace: string): Logger;
24
49
  log(message: unknown, ...optionalParams: unknown[]): void;
25
50
  error(message: unknown, ...optionalParams: unknown[]): void;
26
51
  warn(message: unknown, ...optionalParams: unknown[]): void;
27
52
  debug(message: unknown, ...optionalParams: unknown[]): void;
28
53
  verbose(message: unknown, ...optionalParams: unknown[]): void;
54
+ private emit;
29
55
  private formatMessage;
56
+ private collectContext;
57
+ private formatContextObj;
30
58
  }
@@ -17,16 +17,50 @@ export var LogLevel = /*#__PURE__*/ function(LogLevel) {
17
17
  LogLevel[LogLevel["SILENT"] = 5] = "SILENT";
18
18
  return LogLevel;
19
19
  }({});
20
+ const defaultWriter = (level, line, ...rest)=>{
21
+ if (level === 'ERROR') return console.error(line, ...rest);
22
+ if (level === 'WARN') return console.warn(line, ...rest);
23
+ if (level === 'DEBUG' || level === 'VERBOSE') return console.debug(line, ...rest);
24
+ return console.log(line, ...rest);
25
+ };
26
+ function formatValue(v) {
27
+ if (typeof v === 'string') {
28
+ return /[\s="\\]/.test(v) ? JSON.stringify(v) : v;
29
+ }
30
+ if (typeof v === 'number' || typeof v === 'boolean') return String(v);
31
+ try {
32
+ return JSON.stringify(v);
33
+ } catch {
34
+ return String(v);
35
+ }
36
+ }
20
37
  export class Logger {
21
38
  static level = 2;
22
39
  static globalLogger;
40
+ static globalContextProviders = [];
41
+ static globalWriter = defaultWriter;
23
42
  context;
43
+ instanceContextProviders = [];
44
+ instanceWriter;
24
45
  static setLogLevel(level) {
25
46
  Logger.level = level;
26
47
  }
27
48
  static overrideLogger(logger) {
28
49
  Logger.globalLogger = logger;
29
50
  }
51
+ /** Register a context provider run on every log line from every logger. */ static addContextProvider(provider) {
52
+ Logger.globalContextProviders.push(provider);
53
+ }
54
+ /** Remove all registered global context providers. */ static clearContextProviders() {
55
+ Logger.globalContextProviders = [];
56
+ }
57
+ /** Replace the default console writer. Useful on edge runtimes that have
58
+ * a different output sink (e.g. `env.LOGS.writeDataPoint` on Workers). */ static setWriter(writer) {
59
+ Logger.globalWriter = writer;
60
+ }
61
+ /** Restore the default console-based writer. */ static resetWriter() {
62
+ Logger.globalWriter = defaultWriter;
63
+ }
30
64
  constructor(context){
31
65
  if (context) {
32
66
  this.context = context;
@@ -35,55 +69,86 @@ export class Logger {
35
69
  setContext(context) {
36
70
  this.context = context;
37
71
  }
72
+ /** Add a context provider that runs only for THIS logger instance.
73
+ * Children created via extend() inherit these providers by copy. */ addContextProvider(provider) {
74
+ this.instanceContextProviders.push(provider);
75
+ return this;
76
+ }
77
+ /** Override the writer for this logger (and any extend() children). */ setWriter(writer) {
78
+ this.instanceWriter = writer;
79
+ return this;
80
+ }
81
+ /** Create a child logger with a nested namespace. Context becomes
82
+ * `parent:child`; instance-level providers and writers are inherited
83
+ * by copy so later mutations on either logger stay isolated. */ extend(namespace) {
84
+ const newContext = this.context ? `${this.context}:${namespace}` : namespace;
85
+ const child = new Logger(newContext);
86
+ child.instanceContextProviders = [
87
+ ...this.instanceContextProviders
88
+ ];
89
+ if (this.instanceWriter) child.instanceWriter = this.instanceWriter;
90
+ return child;
91
+ }
38
92
  log(message, ...optionalParams) {
39
- if (Logger.level > 2) return;
40
- if (Logger.globalLogger === false) return;
41
- if (Logger.globalLogger) {
42
- Logger.globalLogger.log(message, ...optionalParams);
43
- return;
44
- }
45
- console.log(this.formatMessage('LOG', message), ...optionalParams);
93
+ this.emit('LOG', 2, message, optionalParams);
46
94
  }
47
95
  error(message, ...optionalParams) {
48
- if (Logger.level > 4) return;
49
- if (Logger.globalLogger === false) return;
50
- if (Logger.globalLogger) {
51
- Logger.globalLogger.error(message, ...optionalParams);
52
- return;
53
- }
54
- console.error(this.formatMessage('ERROR', message), ...optionalParams);
96
+ this.emit('ERROR', 4, message, optionalParams);
55
97
  }
56
98
  warn(message, ...optionalParams) {
57
- if (Logger.level > 3) return;
58
- if (Logger.globalLogger === false) return;
59
- if (Logger.globalLogger) {
60
- Logger.globalLogger.warn(message, ...optionalParams);
61
- return;
62
- }
63
- console.warn(this.formatMessage('WARN', message), ...optionalParams);
99
+ this.emit('WARN', 3, message, optionalParams);
64
100
  }
65
101
  debug(message, ...optionalParams) {
66
- if (Logger.level > 1) return;
67
- if (Logger.globalLogger === false) return;
68
- if (Logger.globalLogger) {
69
- Logger.globalLogger.debug?.(message, ...optionalParams);
70
- return;
71
- }
72
- console.debug(this.formatMessage('DEBUG', message), ...optionalParams);
102
+ this.emit('DEBUG', 1, message, optionalParams);
73
103
  }
74
104
  verbose(message, ...optionalParams) {
75
- if (Logger.level > 0) return;
105
+ this.emit('VERBOSE', 0, message, optionalParams);
106
+ }
107
+ emit(levelName, levelValue, message, rest) {
108
+ if (Logger.level > levelValue) return;
76
109
  if (Logger.globalLogger === false) return;
77
110
  if (Logger.globalLogger) {
78
- Logger.globalLogger.verbose?.(message, ...optionalParams);
111
+ const method = levelName.toLowerCase();
112
+ const fn = Logger.globalLogger[method];
113
+ if (fn) fn.call(Logger.globalLogger, message, ...rest);
79
114
  return;
80
115
  }
81
- console.debug(this.formatMessage('VERBOSE', message), ...optionalParams);
116
+ const line = this.formatMessage(levelName, message);
117
+ const writer = this.instanceWriter ?? Logger.globalWriter;
118
+ writer(levelName, line, ...rest);
82
119
  }
83
120
  formatMessage(level, message) {
84
121
  const timestamp = new Date().toISOString();
85
122
  const ctx = this.context ? ` [${this.context}]` : '';
86
- return `[Vela] ${timestamp} ${level}${ctx} ${message}`;
123
+ const contextStr = this.formatContextObj(this.collectContext());
124
+ return `[Vela] ${timestamp} ${level}${ctx} ${message}${contextStr}`;
125
+ }
126
+ collectContext() {
127
+ const result = {};
128
+ for (const provider of Logger.globalContextProviders){
129
+ try {
130
+ Object.assign(result, provider());
131
+ } catch {
132
+ // Provider threw; drop its contribution and keep going.
133
+ }
134
+ }
135
+ for (const provider of this.instanceContextProviders){
136
+ try {
137
+ Object.assign(result, provider());
138
+ } catch {
139
+ // Same — never let a provider break logging.
140
+ }
141
+ }
142
+ return result;
143
+ }
144
+ formatContextObj(obj) {
145
+ const parts = [];
146
+ for (const key of Object.keys(obj)){
147
+ const value = obj[key];
148
+ if (value === undefined || value === null) continue;
149
+ parts.push(`${key}=${formatValue(value)}`);
150
+ }
151
+ return parts.length > 0 ? ` ${parts.join(' ')}` : '';
87
152
  }
88
153
  }
89
154
  Logger = _ts_decorate([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@velajs/vela",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "NestJS-compatible framework for edge runtimes, powered by Hono",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",