use-term 1.0.0 → 2.0.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 (4) hide show
  1. package/README.md +102 -25
  2. package/package.json +1 -1
  3. package/src/term.d.ts +74 -37
  4. package/src/term.js +118 -50
package/README.md CHANGED
@@ -35,6 +35,57 @@ npm install use-term
35
35
 
36
36
  ---
37
37
 
38
+ ## ⚙️ Configuration
39
+
40
+ You can customize the logger behavior by passing options when creating a new instance:
41
+
42
+ ```javascript
43
+ import { Logger } from "use-term";
44
+
45
+ // Disable all logs (useful for testing or production overrides)
46
+ const silentLogger = new Logger({ silent: true });
47
+ silentLogger.info("This won't be logged");
48
+
49
+ // Disable logs in specific environments (defaults to ["production"])
50
+ const logger = new Logger({
51
+ silentEnvironments: ["production", "staging"],
52
+ environment: process.env.NODE_ENV,
53
+ });
54
+
55
+ // Custom configuration
56
+ const customLogger = new Logger({
57
+ silent: false,
58
+ silentEnvironments: ["prod"],
59
+ environment: process.env.APP_ENV || "development",
60
+ });
61
+ ```
62
+
63
+ ### Configuration Options
64
+
65
+ | Option | Type | Default | Description |
66
+ |--------|------|---------|-------------|
67
+ | `silent` | boolean | `false` | If `true`, all logs are disabled |
68
+ | `silentEnvironments` | string[] | `["production"]` | Array of environments where logging is disabled |
69
+ | `environment` | string | `process.env.NODE_ENV \|\| "development"` | Current environment name |
70
+
71
+ **Example: Disable logs only in production**
72
+
73
+ ```javascript
74
+ const logger = new Logger(); // By default, logs are disabled when NODE_ENV=production
75
+ logger.info("This won't appear in production"); // Silent in production
76
+ ```
77
+
78
+ **Example: Disable logs in multiple environments**
79
+
80
+ ```javascript
81
+ const logger = new Logger({
82
+ silentEnvironments: ["production", "staging", "testing"],
83
+ });
84
+ // Logs will be silenced in any of these environments
85
+ ```
86
+
87
+ ---
88
+
38
89
  ## 🚀 Usage
39
90
 
40
91
  Since `use-term` is built with universal Node.js compatibility in mind, it works seamlessly in both modern **ES Modules (ESM)** and legacy **CommonJS** environments out-of-the-box without requiring separate bundles or transpilation.
@@ -44,37 +95,51 @@ Since `use-term` is built with universal Node.js compatibility in mind, it works
44
95
  For modern Node.js environments (projects with `"type": "module"` in `package.json`), TypeScript, Next.js, or Vite:
45
96
 
46
97
  ```javascript
47
- import term from "use-term";
98
+ import { Logger } from "use-term";
99
+
100
+ // Create a logger instance with default options
101
+ // Logs are disabled in production by default
102
+ const logger = new Logger();
103
+
104
+ // For custom environments:
105
+ const customLogger = new Logger({
106
+ environment: process.env.NODE_ENV,
107
+ silentEnvironments: ["production", "staging"],
108
+ });
48
109
 
49
110
  // --- A. Using inside a class (automatically gets class name) ---
50
111
  class AuthService {
51
112
  login() {
52
- term.info(this, "Starting login process...");
113
+ logger.info("Starting login process...", undefined, this);
53
114
 
54
115
  const user = { id: 42, name: "Alex", roles: ["admin", "billing"] };
55
- term.success(this, "Credentials validated successfully", user);
116
+ logger.success("Credentials validated successfully", user, this);
56
117
  }
57
118
  }
58
119
 
59
120
  // --- B. Using inside a function (automatically gets function name) ---
60
121
  function processPayment() {
61
- term.warn(processPayment, "Payment gateway is responding slowly", {
62
- delayMs: 1500,
63
- });
64
- term.error(processPayment, "Payment gateway connection timeout", {
65
- code: "ETIMEDOUT",
66
- });
122
+ logger.warn(
123
+ "Payment gateway is responding slowly",
124
+ { delayMs: 1500 },
125
+ processPayment,
126
+ );
127
+ logger.error(
128
+ "Payment gateway connection timeout",
129
+ { code: "ETIMEDOUT" },
130
+ processPayment,
131
+ );
67
132
  }
68
133
 
69
134
  // --- C. Using custom string scopes ---
70
- term.info("Server", "Server initialized on port 3000", { env: "production" });
135
+ logger.info("Server initialized on port 3000", { env: "production" }, "Server");
71
136
 
72
137
  // --- D. Visual titles ---
73
- term.title("Authentication Flow");
138
+ logger.title("Authentication Flow");
74
139
  const auth = new AuthService();
75
140
  auth.login();
76
141
 
77
- term.title("Payment Flow");
142
+ logger.title("Payment Flow");
78
143
  processPayment();
79
144
  ```
80
145
 
@@ -85,20 +150,30 @@ processPayment();
85
150
  For traditional Node.js applications:
86
151
 
87
152
  ```javascript
88
- const term = require("use-term");
153
+ const { Logger } = require("use-term");
154
+
155
+ // Create a logger instance with default options
156
+ // Logs are disabled in production by default
157
+ const logger = new Logger();
158
+
159
+ // For custom environments:
160
+ const customLogger = new Logger({
161
+ environment: process.env.NODE_ENV,
162
+ silentEnvironments: ["prod"],
163
+ });
89
164
 
90
165
  // Easily log with CommonJS:
91
- term.info("CJS", "Logging using standard require() syntax!");
166
+ logger.info("Logging using standard require() syntax!", undefined, "CJS");
92
167
 
93
168
  class AuthService {
94
169
  login() {
95
- term.info(this, "Starting login process...");
170
+ logger.info("Starting login process...", undefined, this);
96
171
  const user = { id: 42, name: "Alex", roles: ["admin", "billing"] };
97
- term.success(this, "Credentials validated successfully", user);
172
+ logger.success("Credentials validated successfully", user, this);
98
173
  }
99
174
  }
100
175
 
101
- term.title("CommonJS Demo");
176
+ logger.title("CommonJS Demo");
102
177
  const auth = new AuthService();
103
178
  auth.login();
104
179
  ```
@@ -129,27 +204,27 @@ When you run your scripts, your terminal will light up with premium, high-visibi
129
204
 
130
205
  ## 🛠️ API Reference
131
206
 
132
- ### `term.info(context, message, [data])`
207
+ ### `logger.info(message, [data], [context])`
133
208
 
134
209
  Logs an informational message.
135
210
 
136
- - `context` `(any)`: `this` inside a class, a function name, or a plain string.
137
211
  - `message` `(string)`: The description text of the log.
138
212
  - `data` `(any, optional)`: Any object, array, or metadata to inspect and format below.
213
+ - `context` `(any, optional)`: `this` inside a class, a function name, or a plain string.
139
214
 
140
- ### `term.error(context, message, [data])`
215
+ ### `logger.error(message, [data], [context])`
141
216
 
142
217
  Logs an error message. Same signature as `info()`.
143
218
 
144
- ### `term.success(context, message, [data])`
219
+ ### `logger.success(message, [data], [context])`
145
220
 
146
221
  Logs a success message. Same signature as `info()`.
147
222
 
148
- ### `term.warn(context, message, [data])`
223
+ ### `logger.warn(message, [data], [context])`
149
224
 
150
225
  Logs a warning message. Same signature as `info()`.
151
226
 
152
- ### `term.title(message)`
227
+ ### `logger.title(message)`
153
228
 
154
229
  Prints a highlighted, uppercase section divider to demarcate different stages in your runtime.
155
230
 
@@ -162,9 +237,11 @@ Prints a highlighted, uppercase section divider to demarcate different stages in
162
237
  Autocompletion works out of the box in VS Code and modern IDEs. If you are using TypeScript:
163
238
 
164
239
  ```typescript
165
- import term from "use-term";
240
+ import { Logger } from "use-term";
241
+
242
+ const logger = new Logger();
166
243
 
167
- term.info("TypeScript", "Fully typed logger out of the box!");
244
+ logger.info("Fully typed logger out of the box!", undefined, "TypeScript");
168
245
  ```
169
246
 
170
247
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "use-term",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "A zero-dependency, ultra-lightweight, and beautiful terminal logging library for Node.js with smart context detection, colored outputs, and automatic timestamps.",
5
5
  "main": "src/term.js",
6
6
  "types": "src/term.d.ts",
package/src/term.d.ts CHANGED
@@ -1,45 +1,82 @@
1
+ /**
2
+ * Configuration options for the Logger.
3
+ */
4
+ export interface LoggerOptions {
5
+ /**
6
+ * If true, no logs will be printed regardless of environment.
7
+ * @default false
8
+ */
9
+ silent?: boolean;
10
+ /**
11
+ * Array of environments where logging should be disabled.
12
+ * @default ["production"]
13
+ */
14
+ silentEnvironments?: string[];
15
+ /**
16
+ * Current environment (defaults to NODE_ENV or "development").
17
+ * @default process.env.NODE_ENV || "development"
18
+ */
19
+ environment?: string;
20
+ }
21
+
1
22
  /**
2
23
  * A beautiful, simple, and dependency-free terminal logger for Node.js.
24
+ * Instantiate with `new Logger()` to create a logger instance with optional configuration.
25
+ *
26
+ * @example
27
+ * const logger = new Logger();
28
+ * logger.info("Hello world");
29
+ *
30
+ * @example
31
+ * const logger = new Logger({ silent: true });
32
+ * logger.info("This won't be logged");
33
+ *
34
+ * @example
35
+ * const logger = new Logger({ silentEnvironments: ["production", "staging"] });
36
+ * // Logs will be disabled if NODE_ENV is "production" or "staging"
3
37
  */
4
- declare class Term {
5
- /**
6
- * Logs an informational message.
7
- * @param context The context of the log (e.g. `this`, a class instance, a function reference, or a string).
8
- * @param msg The message to log.
9
- * @param data Optional metadata or object to inspect.
10
- */
11
- info(context: any, msg: string, data?: any): void;
38
+ export class Logger {
39
+ constructor(options?: LoggerOptions);
12
40
 
13
- /**
14
- * Logs an error message.
15
- * @param context The context of the log (e.g. `this`, a class instance, a function reference, or a string).
16
- * @param msg The message to log.
17
- * @param data Optional metadata or object to inspect.
18
- */
19
- error(context: any, msg: string, data?: any): void;
41
+ /**
42
+ * Logs an informational message.
43
+ * @param msg The message to log.
44
+ * @param data Optional metadata or object to inspect.
45
+ * @param context Optional scope or location for the log (e.g. `this`, a function, or a string).
46
+ */
47
+ info(msg: string, data?: any, context?: any): void;
48
+ info(context: any, msg: string, data?: any): void;
20
49
 
21
- /**
22
- * Logs a success message.
23
- * @param context The context of the log (e.g. `this`, a class instance, a function reference, or a string).
24
- * @param msg The message to log.
25
- * @param data Optional metadata or object to inspect.
26
- */
27
- success(context: any, msg: string, data?: any): void;
50
+ /**
51
+ * Logs an error message.
52
+ * @param msg The message to log.
53
+ * @param data Optional metadata or object to inspect.
54
+ * @param context Optional scope or location for the log (e.g. `this`, a function, or a string).
55
+ */
56
+ error(msg: string, data?: any, context?: any): void;
57
+ error(context: any, msg: string, data?: any): void;
28
58
 
29
- /**
30
- * Logs a warning message.
31
- * @param context The context of the log (e.g. `this`, a class instance, a function reference, or a string).
32
- * @param msg The message to log.
33
- * @param data Optional metadata or object to inspect.
34
- */
35
- warn(context: any, msg: string, data?: any): void;
59
+ /**
60
+ * Logs a success message.
61
+ * @param msg The message to log.
62
+ * @param data Optional metadata or object to inspect.
63
+ * @param context Optional scope or location for the log (e.g. `this`, a function, or a string).
64
+ */
65
+ success(msg: string, data?: any, context?: any): void;
66
+ success(context: any, msg: string, data?: any): void;
36
67
 
37
- /**
38
- * Prints a bold, beautifully stylized title separator in the console.
39
- * @param msg The section title to display.
40
- */
41
- title(msg: string): void;
42
- }
68
+ /**
69
+ * Logs a warning message.
70
+ * @param msg The message to log.
71
+ * @param data Optional metadata or object to inspect.
72
+ * @param context Optional scope or location for the log (e.g. `this`, a function, or a string).
73
+ */
74
+ warn(msg: string, data?: any, context?: any): void;
75
+ warn(context: any, msg: string, data?: any): void;
43
76
 
44
- declare const term: Term;
45
- export = term;
77
+ /**
78
+ * Prints a bold, beautifully stylized title separator in the console.
79
+ * @param msg The section title to display.
80
+ */
81
+ title(msg: string): void;
82
+ }
package/src/term.js CHANGED
@@ -1,66 +1,134 @@
1
- const util = require('util');
1
+ const util = require("util");
2
+
3
+ const DEFAULT_OPTIONS = {
4
+ silent: false,
5
+ silentEnvironments: ["production"],
6
+ environment: process.env.NODE_ENV || "development",
7
+ };
2
8
 
3
9
  const COLORS = {
4
- info: '\x1b[36m',
5
- error: '\x1b[31m',
6
- success: '\x1b[32m',
7
- warn: '\x1b[33m',
8
- blue: '\x1b[34m',
9
- gray: '\x1b[90m',
10
- magenta: '\x1b[35m',
11
- reset: '\x1b[0m',
12
- bold: '\x1b[1m'
10
+ info: "\x1b[36m",
11
+ error: "\x1b[31m",
12
+ success: "\x1b[32m",
13
+ warn: "\x1b[33m",
14
+ blue: "\x1b[34m",
15
+ gray: "\x1b[90m",
16
+ magenta: "\x1b[35m",
17
+ reset: "\x1b[0m",
18
+ bold: "\x1b[1m",
13
19
  };
14
20
 
15
21
  class Term {
16
- _timestamp() {
17
- const now = new Date();
18
- const time = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}`;
19
- return `${COLORS.gray}${time}${COLORS.reset}`;
20
- }
22
+ constructor(options = {}) {
23
+ this.config = {
24
+ ...DEFAULT_OPTIONS,
25
+ ...options,
26
+ };
27
+ }
21
28
 
22
- _getContextName(ctx) {
23
- if (!ctx) return 'App';
24
- if (typeof ctx === 'string') return ctx;
25
- if (typeof ctx === 'function') return ctx.name || 'AnonymousFn';
26
- if (typeof ctx === 'object' && ctx.constructor) return ctx.constructor.name;
27
- return 'Unknown';
29
+ _shouldLog() {
30
+ if (this.config.silent) return false;
31
+ if (this.config.silentEnvironments.includes(this.config.environment)) {
32
+ return false;
28
33
  }
34
+ return true;
35
+ }
29
36
 
30
- _log(type, color, icon, context, msg, data) {
31
- const ctxName = this._getContextName(context);
32
- const timestamp = this._timestamp();
33
- const tag = `${color}${icon} ${type}${COLORS.reset}`;
34
- const scope = `${COLORS.blue}[${ctxName}]${COLORS.reset}`;
35
-
36
- console.log(`${timestamp} ${tag} ${scope} ${msg}`);
37
-
38
- if (data !== undefined && data !== null) {
39
- const formatted = util.inspect(data, { colors: true, depth: null });
40
- const indented = formatted.split('\n').map(l => l).join('\n');
41
- console.log(indented);
42
- }
43
- }
37
+ _timestamp() {
38
+ const now = new Date();
39
+ const time = `${now.getHours().toString().padStart(2, "0")}:${now.getMinutes().toString().padStart(2, "0")}:${now.getSeconds().toString().padStart(2, "0")}`;
40
+ return `${COLORS.gray}${time}${COLORS.reset}`;
41
+ }
44
42
 
45
- info(context, msg, data) {
46
- this._log('INFO', COLORS.info, 'ℹ️ ', context, msg, data);
47
- }
43
+ _getContextName(ctx) {
44
+ if (!ctx) return "App";
45
+ if (typeof ctx === "string") return ctx;
46
+ if (typeof ctx === "function") return ctx.name || "AnonymousFn";
47
+ if (typeof ctx === "object" && ctx.constructor) return ctx.constructor.name;
48
+ return "Unknown";
49
+ }
48
50
 
49
- error(context, msg, data) {
50
- this._log('ERROR', COLORS.error, '❌', context, msg, data);
51
- }
52
-
53
- success(context, msg, data) {
54
- this._log('SUCCESS', COLORS.success, '✅', context, msg, data);
51
+ _resolveLogArgs(first, second, third) {
52
+ if (typeof first === "string" && typeof second !== "string") {
53
+ const msg = first;
54
+ if (third !== undefined) {
55
+ return { context: third, msg, data: second };
56
+ }
57
+ if (second === undefined) {
58
+ return { context: undefined, msg, data: undefined };
59
+ }
60
+ if (typeof second === "function" || typeof second === "string") {
61
+ return { context: second, msg, data: undefined };
62
+ }
63
+ return { context: undefined, msg, data: second };
55
64
  }
56
65
 
57
- warn(context, msg, data) {
58
- this._log('WARN', COLORS.warn, '⚠️ ', context, msg, data);
59
- }
66
+ return { context: first, msg: second, data: third };
67
+ }
68
+
69
+ _log(type, color, icon, context, msg, data) {
70
+ if (!this._shouldLog()) return;
60
71
 
61
- title(msg) {
62
- console.log(`\n${COLORS.magenta}${COLORS.bold}━━━ ${msg.toUpperCase()} ━━━${COLORS.reset}`);
72
+ const ctxName = this._getContextName(context);
73
+ const timestamp = this._timestamp();
74
+ const tag = `${color}${icon} ${type}${COLORS.reset}`;
75
+ const scope = `${COLORS.blue}[${ctxName}]${COLORS.reset}`;
76
+
77
+ console.log(`${timestamp} ${tag} ${scope} ${msg}`);
78
+
79
+ if (data !== undefined && data !== null) {
80
+ const formatted = util.inspect(data, { colors: true, depth: null });
81
+ const indented = formatted
82
+ .split("\n")
83
+ .map((l) => l)
84
+ .join("\n");
85
+ console.log(indented);
63
86
  }
87
+ }
88
+
89
+ info(msgOrContext, dataOrMsg, context) {
90
+ const {
91
+ context: ctx,
92
+ msg,
93
+ data,
94
+ } = this._resolveLogArgs(msgOrContext, dataOrMsg, context);
95
+ this._log("INFO", COLORS.info, "ℹ️ ", ctx, msg, data);
96
+ }
97
+
98
+ error(msgOrContext, dataOrMsg, context) {
99
+ const {
100
+ context: ctx,
101
+ msg,
102
+ data,
103
+ } = this._resolveLogArgs(msgOrContext, dataOrMsg, context);
104
+ this._log("ERROR", COLORS.error, "❌", ctx, msg, data);
105
+ }
106
+
107
+ success(msgOrContext, dataOrMsg, context) {
108
+ const {
109
+ context: ctx,
110
+ msg,
111
+ data,
112
+ } = this._resolveLogArgs(msgOrContext, dataOrMsg, context);
113
+ this._log("SUCCESS", COLORS.success, "✅", ctx, msg, data);
114
+ }
115
+
116
+ warn(msgOrContext, dataOrMsg, context) {
117
+ const {
118
+ context: ctx,
119
+ msg,
120
+ data,
121
+ } = this._resolveLogArgs(msgOrContext, dataOrMsg, context);
122
+ this._log("WARN", COLORS.warn, "⚠️ ", ctx, msg, data);
123
+ }
124
+
125
+ title(msg) {
126
+ if (!this._shouldLog()) return;
127
+
128
+ console.log(
129
+ `\n${COLORS.magenta}${COLORS.bold}━━━ ${msg.toUpperCase()} ━━━${COLORS.reset}`,
130
+ );
131
+ }
64
132
  }
65
133
 
66
- module.exports = new Term();
134
+ module.exports = Term;