@nmakarov/cli-toolkit 0.1.1 → 0.1.2

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.
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/logger/index.ts
31
+ var logger_exports = {};
32
+ __export(logger_exports, {
33
+ CliToolkitLogger: () => CliToolkitLogger
34
+ });
35
+ module.exports = __toCommonJS(logger_exports);
36
+ var import_chalk = __toESM(require("chalk"), 1);
37
+ var import_util = __toESM(require("util"), 1);
38
+
39
+ // src/logger/transports.ts
40
+ var ConsoleTransport = class {
41
+ write(payload) {
42
+ console.info(payload);
43
+ }
44
+ };
45
+ var ParentProcessTransport = class {
46
+ write(payload) {
47
+ if (typeof process.send === "function") {
48
+ process.send(payload);
49
+ } else {
50
+ console.info(payload);
51
+ }
52
+ }
53
+ };
54
+
55
+ // src/logger/index.ts
56
+ var ALL_LEVELS = [
57
+ "silly",
58
+ "debug",
59
+ "logic",
60
+ "info",
61
+ "notice",
62
+ "warn",
63
+ "error",
64
+ "results",
65
+ "request",
66
+ "response",
67
+ "progress"
68
+ ];
69
+ var LEVEL_COLORS = {
70
+ error: import_chalk.default.red.bold,
71
+ warn: import_chalk.default.rgb(255, 165, 0),
72
+ notice: import_chalk.default.cyan,
73
+ info: import_chalk.default.white.bold,
74
+ logic: import_chalk.default.gray,
75
+ debug: import_chalk.default.gray,
76
+ silly: import_chalk.default.gray,
77
+ request: import_chalk.default.green,
78
+ response: import_chalk.default.yellow,
79
+ progress: import_chalk.default.green,
80
+ results: import_chalk.default.magenta
81
+ };
82
+ var CliToolkitLogger = class {
83
+ options;
84
+ transport;
85
+ startTimes = {};
86
+ lastProgressTimes = {};
87
+ constructor(options = {}) {
88
+ this.options = this.normalizeOptions(options);
89
+ this.transport = this.options.route === "ipc" ? new ParentProcessTransport() : new ConsoleTransport();
90
+ }
91
+ setMode(mode) {
92
+ if (!this.isValidMode(mode)) {
93
+ throw new Error(`Unsupported logger mode: ${mode}`);
94
+ }
95
+ this.options.mode = mode;
96
+ }
97
+ debug(message, ...chunks) {
98
+ this.out({ level: "debug", message, chunks });
99
+ }
100
+ info(message, ...chunks) {
101
+ this.out({ level: "info", message, chunks });
102
+ }
103
+ notice(message, ...chunks) {
104
+ this.out({ level: "notice", message, chunks });
105
+ }
106
+ warn(message, ...chunks) {
107
+ this.out({ level: "warn", message, chunks });
108
+ }
109
+ error(message, ...chunks) {
110
+ this.out({ level: "error", message, chunks });
111
+ }
112
+ logic(message, ...chunks) {
113
+ this.out({ level: "logic", message, chunks });
114
+ }
115
+ silly(message, ...chunks) {
116
+ this.out({ level: "silly", message, chunks });
117
+ }
118
+ results(results) {
119
+ this.out({ level: "results", message: "results", results });
120
+ }
121
+ request(operation, ...chunks) {
122
+ const message = this.inspectChunks([operation, ...chunks]);
123
+ this.out({ level: "request", message });
124
+ }
125
+ response(operation, ...chunks) {
126
+ const message = this.inspectChunks([operation, ...chunks]);
127
+ this.out({ level: "response", message });
128
+ }
129
+ progress(message, opts) {
130
+ const { prefix, count, total } = opts;
131
+ const paddedTotal = String(total).length;
132
+ const paddedCount = String(count).padStart(paddedTotal, " ");
133
+ const payload = {
134
+ level: "progress",
135
+ message,
136
+ count: paddedCount,
137
+ total,
138
+ prefix
139
+ };
140
+ if (!this.startTimes[prefix ?? ""]) {
141
+ this.startTimes[prefix ?? ""] = Date.now();
142
+ }
143
+ if (this.options.progressTimes) {
144
+ const elapsedSeconds = (Date.now() - this.startTimes[prefix ?? ""]) / 1e3;
145
+ let remaining = -1;
146
+ if (count > 1) {
147
+ const rate = elapsedSeconds / (count - 1);
148
+ remaining = (total - count) * rate;
149
+ }
150
+ payload.elapsed = this.round(elapsedSeconds, 2);
151
+ payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;
152
+ }
153
+ if (count >= total) {
154
+ delete this.startTimes[prefix ?? ""];
155
+ delete this.lastProgressTimes[prefix ?? ""];
156
+ }
157
+ if (this.shouldOutputProgress(prefix ?? "", count, total)) {
158
+ this.out(payload);
159
+ if (this.options.progressThrottle && prefix) {
160
+ this.lastProgressTimes[prefix] = Date.now();
161
+ }
162
+ }
163
+ }
164
+ shouldOutputProgress(prefix, count, total) {
165
+ if (!this.options.progressThrottle) {
166
+ return true;
167
+ }
168
+ if (count === 1 || count === total || !prefix) {
169
+ return true;
170
+ }
171
+ const lastTime = this.lastProgressTimes[prefix];
172
+ if (!lastTime) {
173
+ return true;
174
+ }
175
+ return Date.now() - lastTime >= this.options.progressThrottle;
176
+ }
177
+ out(struct) {
178
+ if (this.options.silent) {
179
+ return;
180
+ }
181
+ if (!this.options.levels.includes(struct.level)) {
182
+ return;
183
+ }
184
+ if (this.options.prefix && !struct.prefix) {
185
+ struct.prefix = this.options.prefix;
186
+ }
187
+ const output = this.options.mode === "json" ? struct : this.formatLog(struct);
188
+ this.transport.write(output);
189
+ }
190
+ formatLog(struct) {
191
+ const parts = [];
192
+ const now = /* @__PURE__ */ new Date();
193
+ if (this.options.timestamp) {
194
+ parts.push(now.toISOString());
195
+ }
196
+ if (this.options.showLevel) {
197
+ parts.push(struct.level.toUpperCase());
198
+ }
199
+ if (struct.level === "progress") {
200
+ if (struct.prefix) {
201
+ parts.push(LEVEL_COLORS[struct.level].bold(struct.prefix));
202
+ }
203
+ if (struct.count !== void 0 && struct.total !== void 0) {
204
+ parts.push(LEVEL_COLORS[struct.level](`${struct.count}/${struct.total}`));
205
+ }
206
+ } else if (struct.prefix) {
207
+ parts.push(import_chalk.default.cyan(`[${struct.prefix}]`));
208
+ }
209
+ if (struct.message) {
210
+ const formatter = LEVEL_COLORS[struct.level] ?? import_chalk.default.white;
211
+ parts.push(formatter.bold(struct.message));
212
+ }
213
+ if (struct.level === "progress") {
214
+ if (struct.elapsed !== void 0 && struct.remaining !== void 0) {
215
+ const formatter = LEVEL_COLORS[struct.level];
216
+ parts.push(formatter(`${struct.elapsed}/${struct.remaining}`));
217
+ }
218
+ }
219
+ if (struct.chunks && struct.chunks.length) {
220
+ parts.push(this.inspectChunks(struct.chunks));
221
+ }
222
+ if (struct.results) {
223
+ const formatter = LEVEL_COLORS[struct.level] ?? import_chalk.default.white;
224
+ parts.push(formatter(JSON.stringify(struct.results, null, 4)));
225
+ }
226
+ return parts.join(" ");
227
+ }
228
+ inspectChunks(chunks) {
229
+ return chunks.map((chunk) => import_util.default.inspect(chunk, { colors: true, depth: null })).join(" ");
230
+ }
231
+ normalizeOptions(options) {
232
+ const { route, mode, prefix, silent, showLevel, timestamp, levels, progress } = options;
233
+ const normalized = {
234
+ mode: this.isValidMode(mode) ? mode : "text",
235
+ route: route ?? (typeof process.send === "function" ? "ipc" : "console"),
236
+ prefix,
237
+ silent: silent ?? false,
238
+ showLevel: showLevel ?? true,
239
+ timestamp: timestamp ?? false,
240
+ levels: this.normalizeLevels(levels),
241
+ progressTimes: progress?.withTimes ?? false,
242
+ progressThrottle: progress?.throttleMs
243
+ };
244
+ return normalized;
245
+ }
246
+ normalizeLevels(levels) {
247
+ if (!levels || !levels.length) {
248
+ return ALL_LEVELS;
249
+ }
250
+ const includes = levels.filter((level) => !level.startsWith("-"));
251
+ const excludes = levels.filter((level) => level.startsWith("-")).map((level) => level.slice(1));
252
+ const unknown = [...includes, ...excludes].filter((level) => !ALL_LEVELS.includes(level));
253
+ if (unknown.length) {
254
+ console.warn(`[Logger] Unknown level(s): ${unknown.join(", ")}`);
255
+ }
256
+ const base = includes.length ? includes : ALL_LEVELS;
257
+ return base.filter((level) => !excludes.includes(level));
258
+ }
259
+ isValidMode(mode) {
260
+ return mode === void 0 || mode === null || mode === "text" || mode === "json";
261
+ }
262
+ round(value, places) {
263
+ const factor = Math.pow(10, places);
264
+ return Math.round(value * factor) / factor;
265
+ }
266
+ };
267
+ // Annotate the CommonJS export names for ESM import in node:
268
+ 0 && (module.exports = {
269
+ CliToolkitLogger
270
+ });
271
+ //# sourceMappingURL=logger.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logger/index.ts","../src/logger/transports.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport util from \"util\";\n\nimport {\n Logger,\n LoggerOptions,\n LoggerProgressOptions,\n LogPayload,\n LevelName,\n LoggerTransport,\n LoggerMode\n} from \"./types.js\";\nimport { ConsoleTransport, ParentProcessTransport } from \"./transports.js\";\n\nconst ALL_LEVELS: LevelName[] = [\n \"silly\",\n \"debug\",\n \"logic\",\n \"info\",\n \"notice\",\n \"warn\",\n \"error\",\n \"results\",\n \"request\",\n \"response\",\n \"progress\"\n];\n\nconst LEVEL_COLORS: Record<LevelName, chalk.Chalk> = {\n error: chalk.red.bold,\n warn: chalk.rgb(255, 165, 0),\n notice: chalk.cyan,\n info: chalk.white.bold,\n logic: chalk.gray,\n debug: chalk.gray,\n silly: chalk.gray,\n request: chalk.green,\n response: chalk.yellow,\n progress: chalk.green,\n results: chalk.magenta\n};\n\ninterface NormalizedOptions {\n mode: LoggerMode;\n route: \"console\" | \"ipc\";\n prefix?: string;\n silent: boolean;\n showLevel: boolean;\n timestamp: boolean;\n levels: LevelName[];\n progressTimes: boolean;\n progressThrottle?: number;\n}\n\nexport class CliToolkitLogger implements Logger {\n private readonly options: NormalizedOptions;\n private transport: LoggerTransport;\n private readonly startTimes: Record<string, number> = {};\n private readonly lastProgressTimes: Record<string, number> = {};\n\n constructor(options: LoggerOptions = {}) {\n this.options = this.normalizeOptions(options);\n this.transport = this.options.route === \"ipc\"\n ? new ParentProcessTransport()\n : new ConsoleTransport();\n }\n\n setMode(mode: LoggerMode): void {\n if (!this.isValidMode(mode)) {\n throw new Error(`Unsupported logger mode: ${mode}`);\n }\n this.options.mode = mode;\n }\n\n debug(message?: any, ...chunks: any[]): void {\n this.out({ level: \"debug\", message, chunks });\n }\n\n info(message?: any, ...chunks: any[]): void {\n this.out({ level: \"info\", message, chunks });\n }\n\n notice(message?: any, ...chunks: any[]): void {\n this.out({ level: \"notice\", message, chunks });\n }\n\n warn(message?: any, ...chunks: any[]): void {\n this.out({ level: \"warn\", message, chunks });\n }\n\n error(message?: any, ...chunks: any[]): void {\n this.out({ level: \"error\", message, chunks });\n }\n\n logic(message?: any, ...chunks: any[]): void {\n this.out({ level: \"logic\", message, chunks });\n }\n\n silly(message?: any, ...chunks: any[]): void {\n this.out({ level: \"silly\", message, chunks });\n }\n\n results(results: unknown): void {\n this.out({ level: \"results\", message: \"results\", results });\n }\n\n request(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"request\", message });\n }\n\n response(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"response\", message });\n }\n\n progress(message: string, opts: LoggerProgressOptions): void {\n const { prefix, count, total } = opts;\n const paddedTotal = String(total).length;\n const paddedCount = String(count).padStart(paddedTotal, \" \");\n const payload: LogPayload = {\n level: \"progress\",\n message,\n count: paddedCount,\n total,\n prefix\n };\n\n if (!this.startTimes[prefix ?? \"\"]) {\n this.startTimes[prefix ?? \"\"] = Date.now();\n }\n if (this.options.progressTimes) {\n const elapsedSeconds = (Date.now() - this.startTimes[prefix ?? \"\"]) / 1000;\n let remaining = -1;\n if (count > 1) {\n const rate = elapsedSeconds / (count - 1);\n remaining = (total - count) * rate;\n }\n payload.elapsed = this.round(elapsedSeconds, 2);\n payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;\n }\n\n if (count >= total) {\n delete this.startTimes[prefix ?? \"\"];\n delete this.lastProgressTimes[prefix ?? \"\"];\n }\n\n if (this.shouldOutputProgress(prefix ?? \"\", count, total)) {\n this.out(payload);\n if (this.options.progressThrottle && prefix) {\n this.lastProgressTimes[prefix] = Date.now();\n }\n }\n }\n\n private shouldOutputProgress(prefix: string, count: number, total: number): boolean {\n if (!this.options.progressThrottle) {\n return true;\n }\n if (count === 1 || count === total || !prefix) {\n return true;\n }\n const lastTime = this.lastProgressTimes[prefix];\n if (!lastTime) {\n return true;\n }\n return Date.now() - lastTime >= this.options.progressThrottle;\n }\n\n private out(struct: LogPayload): void {\n if (this.options.silent) {\n return;\n }\n if (!this.options.levels.includes(struct.level)) {\n return;\n }\n\n if (this.options.prefix && !struct.prefix) {\n struct.prefix = this.options.prefix;\n }\n\n const output = this.options.mode === \"json\"\n ? struct\n : this.formatLog(struct);\n\n this.transport.write(output);\n }\n\n private formatLog(struct: LogPayload): string {\n const parts: string[] = [];\n const now = new Date();\n\n if (this.options.timestamp) {\n parts.push(now.toISOString());\n }\n\n if (this.options.showLevel) {\n parts.push(struct.level.toUpperCase());\n }\n\n if (struct.level === \"progress\") {\n if (struct.prefix) {\n parts.push(LEVEL_COLORS[struct.level].bold(struct.prefix));\n }\n if (struct.count !== undefined && struct.total !== undefined) {\n parts.push(LEVEL_COLORS[struct.level](`${struct.count}/${struct.total}`));\n }\n } else if (struct.prefix) {\n parts.push(chalk.cyan(`[${struct.prefix}]`));\n }\n\n if (struct.message) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter.bold(struct.message));\n }\n\n if (struct.level === \"progress\") {\n if (struct.elapsed !== undefined && struct.remaining !== undefined) {\n const formatter = LEVEL_COLORS[struct.level];\n parts.push(formatter(`${struct.elapsed}/${struct.remaining}`));\n }\n }\n\n if (struct.chunks && struct.chunks.length) {\n parts.push(this.inspectChunks(struct.chunks));\n }\n\n if (struct.results) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter(JSON.stringify(struct.results, null, 4)));\n }\n\n return parts.join(\" \");\n }\n\n private inspectChunks(chunks: any[]): string {\n return chunks\n .map(chunk => util.inspect(chunk, { colors: true, depth: null }))\n .join(\" \");\n }\n\n private normalizeOptions(options: LoggerOptions): NormalizedOptions {\n const { route, mode, prefix, silent, showLevel, timestamp, levels, progress } = options;\n const normalized: NormalizedOptions = {\n mode: this.isValidMode(mode) ? mode! : \"text\",\n route: route ?? (typeof process.send === \"function\" ? \"ipc\" : \"console\"),\n prefix,\n silent: silent ?? false,\n showLevel: showLevel ?? true,\n timestamp: timestamp ?? false,\n levels: this.normalizeLevels(levels),\n progressTimes: progress?.withTimes ?? false,\n progressThrottle: progress?.throttleMs\n };\n return normalized;\n }\n\n private normalizeLevels(levels?: string[]): LevelName[] {\n if (!levels || !levels.length) {\n return ALL_LEVELS;\n }\n\n const includes = levels.filter(level => !level.startsWith(\"-\")) as LevelName[];\n const excludes = levels\n .filter(level => level.startsWith(\"-\"))\n .map(level => level.slice(1)) as LevelName[];\n\n const unknown = [...includes, ...excludes].filter(level => !ALL_LEVELS.includes(level));\n if (unknown.length) {\n console.warn(`[Logger] Unknown level(s): ${unknown.join(\", \")}`);\n }\n\n const base = includes.length ? includes : ALL_LEVELS;\n return base.filter(level => !excludes.includes(level));\n }\n\n private isValidMode(mode?: string | null): mode is LoggerMode | undefined {\n return mode === undefined || mode === null || mode === \"text\" || mode === \"json\";\n }\n\n private round(value: number, places: number): number {\n const factor = Math.pow(10, places);\n return Math.round(value * factor) / factor;\n }\n}\n\n\n","import { LoggerTransport } from \"./types.js\";\n\nexport class ConsoleTransport implements LoggerTransport {\n write(payload: any): void {\n console.info(payload);\n }\n}\n\nexport class ParentProcessTransport implements LoggerTransport {\n write(payload: any): void {\n if (typeof process.send === \"function\") {\n process.send(payload);\n } else {\n console.info(payload);\n }\n }\n}\n\n\n"],"mappings":"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","names":["chalk","util"]}
package/dist/logger.js ADDED
@@ -0,0 +1,236 @@
1
+ // src/logger/index.ts
2
+ import chalk from "chalk";
3
+ import util from "util";
4
+
5
+ // src/logger/transports.ts
6
+ var ConsoleTransport = class {
7
+ write(payload) {
8
+ console.info(payload);
9
+ }
10
+ };
11
+ var ParentProcessTransport = class {
12
+ write(payload) {
13
+ if (typeof process.send === "function") {
14
+ process.send(payload);
15
+ } else {
16
+ console.info(payload);
17
+ }
18
+ }
19
+ };
20
+
21
+ // src/logger/index.ts
22
+ var ALL_LEVELS = [
23
+ "silly",
24
+ "debug",
25
+ "logic",
26
+ "info",
27
+ "notice",
28
+ "warn",
29
+ "error",
30
+ "results",
31
+ "request",
32
+ "response",
33
+ "progress"
34
+ ];
35
+ var LEVEL_COLORS = {
36
+ error: chalk.red.bold,
37
+ warn: chalk.rgb(255, 165, 0),
38
+ notice: chalk.cyan,
39
+ info: chalk.white.bold,
40
+ logic: chalk.gray,
41
+ debug: chalk.gray,
42
+ silly: chalk.gray,
43
+ request: chalk.green,
44
+ response: chalk.yellow,
45
+ progress: chalk.green,
46
+ results: chalk.magenta
47
+ };
48
+ var CliToolkitLogger = class {
49
+ options;
50
+ transport;
51
+ startTimes = {};
52
+ lastProgressTimes = {};
53
+ constructor(options = {}) {
54
+ this.options = this.normalizeOptions(options);
55
+ this.transport = this.options.route === "ipc" ? new ParentProcessTransport() : new ConsoleTransport();
56
+ }
57
+ setMode(mode) {
58
+ if (!this.isValidMode(mode)) {
59
+ throw new Error(`Unsupported logger mode: ${mode}`);
60
+ }
61
+ this.options.mode = mode;
62
+ }
63
+ debug(message, ...chunks) {
64
+ this.out({ level: "debug", message, chunks });
65
+ }
66
+ info(message, ...chunks) {
67
+ this.out({ level: "info", message, chunks });
68
+ }
69
+ notice(message, ...chunks) {
70
+ this.out({ level: "notice", message, chunks });
71
+ }
72
+ warn(message, ...chunks) {
73
+ this.out({ level: "warn", message, chunks });
74
+ }
75
+ error(message, ...chunks) {
76
+ this.out({ level: "error", message, chunks });
77
+ }
78
+ logic(message, ...chunks) {
79
+ this.out({ level: "logic", message, chunks });
80
+ }
81
+ silly(message, ...chunks) {
82
+ this.out({ level: "silly", message, chunks });
83
+ }
84
+ results(results) {
85
+ this.out({ level: "results", message: "results", results });
86
+ }
87
+ request(operation, ...chunks) {
88
+ const message = this.inspectChunks([operation, ...chunks]);
89
+ this.out({ level: "request", message });
90
+ }
91
+ response(operation, ...chunks) {
92
+ const message = this.inspectChunks([operation, ...chunks]);
93
+ this.out({ level: "response", message });
94
+ }
95
+ progress(message, opts) {
96
+ const { prefix, count, total } = opts;
97
+ const paddedTotal = String(total).length;
98
+ const paddedCount = String(count).padStart(paddedTotal, " ");
99
+ const payload = {
100
+ level: "progress",
101
+ message,
102
+ count: paddedCount,
103
+ total,
104
+ prefix
105
+ };
106
+ if (!this.startTimes[prefix ?? ""]) {
107
+ this.startTimes[prefix ?? ""] = Date.now();
108
+ }
109
+ if (this.options.progressTimes) {
110
+ const elapsedSeconds = (Date.now() - this.startTimes[prefix ?? ""]) / 1e3;
111
+ let remaining = -1;
112
+ if (count > 1) {
113
+ const rate = elapsedSeconds / (count - 1);
114
+ remaining = (total - count) * rate;
115
+ }
116
+ payload.elapsed = this.round(elapsedSeconds, 2);
117
+ payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;
118
+ }
119
+ if (count >= total) {
120
+ delete this.startTimes[prefix ?? ""];
121
+ delete this.lastProgressTimes[prefix ?? ""];
122
+ }
123
+ if (this.shouldOutputProgress(prefix ?? "", count, total)) {
124
+ this.out(payload);
125
+ if (this.options.progressThrottle && prefix) {
126
+ this.lastProgressTimes[prefix] = Date.now();
127
+ }
128
+ }
129
+ }
130
+ shouldOutputProgress(prefix, count, total) {
131
+ if (!this.options.progressThrottle) {
132
+ return true;
133
+ }
134
+ if (count === 1 || count === total || !prefix) {
135
+ return true;
136
+ }
137
+ const lastTime = this.lastProgressTimes[prefix];
138
+ if (!lastTime) {
139
+ return true;
140
+ }
141
+ return Date.now() - lastTime >= this.options.progressThrottle;
142
+ }
143
+ out(struct) {
144
+ if (this.options.silent) {
145
+ return;
146
+ }
147
+ if (!this.options.levels.includes(struct.level)) {
148
+ return;
149
+ }
150
+ if (this.options.prefix && !struct.prefix) {
151
+ struct.prefix = this.options.prefix;
152
+ }
153
+ const output = this.options.mode === "json" ? struct : this.formatLog(struct);
154
+ this.transport.write(output);
155
+ }
156
+ formatLog(struct) {
157
+ const parts = [];
158
+ const now = /* @__PURE__ */ new Date();
159
+ if (this.options.timestamp) {
160
+ parts.push(now.toISOString());
161
+ }
162
+ if (this.options.showLevel) {
163
+ parts.push(struct.level.toUpperCase());
164
+ }
165
+ if (struct.level === "progress") {
166
+ if (struct.prefix) {
167
+ parts.push(LEVEL_COLORS[struct.level].bold(struct.prefix));
168
+ }
169
+ if (struct.count !== void 0 && struct.total !== void 0) {
170
+ parts.push(LEVEL_COLORS[struct.level](`${struct.count}/${struct.total}`));
171
+ }
172
+ } else if (struct.prefix) {
173
+ parts.push(chalk.cyan(`[${struct.prefix}]`));
174
+ }
175
+ if (struct.message) {
176
+ const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;
177
+ parts.push(formatter.bold(struct.message));
178
+ }
179
+ if (struct.level === "progress") {
180
+ if (struct.elapsed !== void 0 && struct.remaining !== void 0) {
181
+ const formatter = LEVEL_COLORS[struct.level];
182
+ parts.push(formatter(`${struct.elapsed}/${struct.remaining}`));
183
+ }
184
+ }
185
+ if (struct.chunks && struct.chunks.length) {
186
+ parts.push(this.inspectChunks(struct.chunks));
187
+ }
188
+ if (struct.results) {
189
+ const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;
190
+ parts.push(formatter(JSON.stringify(struct.results, null, 4)));
191
+ }
192
+ return parts.join(" ");
193
+ }
194
+ inspectChunks(chunks) {
195
+ return chunks.map((chunk) => util.inspect(chunk, { colors: true, depth: null })).join(" ");
196
+ }
197
+ normalizeOptions(options) {
198
+ const { route, mode, prefix, silent, showLevel, timestamp, levels, progress } = options;
199
+ const normalized = {
200
+ mode: this.isValidMode(mode) ? mode : "text",
201
+ route: route ?? (typeof process.send === "function" ? "ipc" : "console"),
202
+ prefix,
203
+ silent: silent ?? false,
204
+ showLevel: showLevel ?? true,
205
+ timestamp: timestamp ?? false,
206
+ levels: this.normalizeLevels(levels),
207
+ progressTimes: progress?.withTimes ?? false,
208
+ progressThrottle: progress?.throttleMs
209
+ };
210
+ return normalized;
211
+ }
212
+ normalizeLevels(levels) {
213
+ if (!levels || !levels.length) {
214
+ return ALL_LEVELS;
215
+ }
216
+ const includes = levels.filter((level) => !level.startsWith("-"));
217
+ const excludes = levels.filter((level) => level.startsWith("-")).map((level) => level.slice(1));
218
+ const unknown = [...includes, ...excludes].filter((level) => !ALL_LEVELS.includes(level));
219
+ if (unknown.length) {
220
+ console.warn(`[Logger] Unknown level(s): ${unknown.join(", ")}`);
221
+ }
222
+ const base = includes.length ? includes : ALL_LEVELS;
223
+ return base.filter((level) => !excludes.includes(level));
224
+ }
225
+ isValidMode(mode) {
226
+ return mode === void 0 || mode === null || mode === "text" || mode === "json";
227
+ }
228
+ round(value, places) {
229
+ const factor = Math.pow(10, places);
230
+ return Math.round(value * factor) / factor;
231
+ }
232
+ };
233
+ export {
234
+ CliToolkitLogger
235
+ };
236
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logger/index.ts","../src/logger/transports.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport util from \"util\";\n\nimport {\n Logger,\n LoggerOptions,\n LoggerProgressOptions,\n LogPayload,\n LevelName,\n LoggerTransport,\n LoggerMode\n} from \"./types.js\";\nimport { ConsoleTransport, ParentProcessTransport } from \"./transports.js\";\n\nconst ALL_LEVELS: LevelName[] = [\n \"silly\",\n \"debug\",\n \"logic\",\n \"info\",\n \"notice\",\n \"warn\",\n \"error\",\n \"results\",\n \"request\",\n \"response\",\n \"progress\"\n];\n\nconst LEVEL_COLORS: Record<LevelName, chalk.Chalk> = {\n error: chalk.red.bold,\n warn: chalk.rgb(255, 165, 0),\n notice: chalk.cyan,\n info: chalk.white.bold,\n logic: chalk.gray,\n debug: chalk.gray,\n silly: chalk.gray,\n request: chalk.green,\n response: chalk.yellow,\n progress: chalk.green,\n results: chalk.magenta\n};\n\ninterface NormalizedOptions {\n mode: LoggerMode;\n route: \"console\" | \"ipc\";\n prefix?: string;\n silent: boolean;\n showLevel: boolean;\n timestamp: boolean;\n levels: LevelName[];\n progressTimes: boolean;\n progressThrottle?: number;\n}\n\nexport class CliToolkitLogger implements Logger {\n private readonly options: NormalizedOptions;\n private transport: LoggerTransport;\n private readonly startTimes: Record<string, number> = {};\n private readonly lastProgressTimes: Record<string, number> = {};\n\n constructor(options: LoggerOptions = {}) {\n this.options = this.normalizeOptions(options);\n this.transport = this.options.route === \"ipc\"\n ? new ParentProcessTransport()\n : new ConsoleTransport();\n }\n\n setMode(mode: LoggerMode): void {\n if (!this.isValidMode(mode)) {\n throw new Error(`Unsupported logger mode: ${mode}`);\n }\n this.options.mode = mode;\n }\n\n debug(message?: any, ...chunks: any[]): void {\n this.out({ level: \"debug\", message, chunks });\n }\n\n info(message?: any, ...chunks: any[]): void {\n this.out({ level: \"info\", message, chunks });\n }\n\n notice(message?: any, ...chunks: any[]): void {\n this.out({ level: \"notice\", message, chunks });\n }\n\n warn(message?: any, ...chunks: any[]): void {\n this.out({ level: \"warn\", message, chunks });\n }\n\n error(message?: any, ...chunks: any[]): void {\n this.out({ level: \"error\", message, chunks });\n }\n\n logic(message?: any, ...chunks: any[]): void {\n this.out({ level: \"logic\", message, chunks });\n }\n\n silly(message?: any, ...chunks: any[]): void {\n this.out({ level: \"silly\", message, chunks });\n }\n\n results(results: unknown): void {\n this.out({ level: \"results\", message: \"results\", results });\n }\n\n request(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"request\", message });\n }\n\n response(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"response\", message });\n }\n\n progress(message: string, opts: LoggerProgressOptions): void {\n const { prefix, count, total } = opts;\n const paddedTotal = String(total).length;\n const paddedCount = String(count).padStart(paddedTotal, \" \");\n const payload: LogPayload = {\n level: \"progress\",\n message,\n count: paddedCount,\n total,\n prefix\n };\n\n if (!this.startTimes[prefix ?? \"\"]) {\n this.startTimes[prefix ?? \"\"] = Date.now();\n }\n if (this.options.progressTimes) {\n const elapsedSeconds = (Date.now() - this.startTimes[prefix ?? \"\"]) / 1000;\n let remaining = -1;\n if (count > 1) {\n const rate = elapsedSeconds / (count - 1);\n remaining = (total - count) * rate;\n }\n payload.elapsed = this.round(elapsedSeconds, 2);\n payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;\n }\n\n if (count >= total) {\n delete this.startTimes[prefix ?? \"\"];\n delete this.lastProgressTimes[prefix ?? \"\"];\n }\n\n if (this.shouldOutputProgress(prefix ?? \"\", count, total)) {\n this.out(payload);\n if (this.options.progressThrottle && prefix) {\n this.lastProgressTimes[prefix] = Date.now();\n }\n }\n }\n\n private shouldOutputProgress(prefix: string, count: number, total: number): boolean {\n if (!this.options.progressThrottle) {\n return true;\n }\n if (count === 1 || count === total || !prefix) {\n return true;\n }\n const lastTime = this.lastProgressTimes[prefix];\n if (!lastTime) {\n return true;\n }\n return Date.now() - lastTime >= this.options.progressThrottle;\n }\n\n private out(struct: LogPayload): void {\n if (this.options.silent) {\n return;\n }\n if (!this.options.levels.includes(struct.level)) {\n return;\n }\n\n if (this.options.prefix && !struct.prefix) {\n struct.prefix = this.options.prefix;\n }\n\n const output = this.options.mode === \"json\"\n ? struct\n : this.formatLog(struct);\n\n this.transport.write(output);\n }\n\n private formatLog(struct: LogPayload): string {\n const parts: string[] = [];\n const now = new Date();\n\n if (this.options.timestamp) {\n parts.push(now.toISOString());\n }\n\n if (this.options.showLevel) {\n parts.push(struct.level.toUpperCase());\n }\n\n if (struct.level === \"progress\") {\n if (struct.prefix) {\n parts.push(LEVEL_COLORS[struct.level].bold(struct.prefix));\n }\n if (struct.count !== undefined && struct.total !== undefined) {\n parts.push(LEVEL_COLORS[struct.level](`${struct.count}/${struct.total}`));\n }\n } else if (struct.prefix) {\n parts.push(chalk.cyan(`[${struct.prefix}]`));\n }\n\n if (struct.message) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter.bold(struct.message));\n }\n\n if (struct.level === \"progress\") {\n if (struct.elapsed !== undefined && struct.remaining !== undefined) {\n const formatter = LEVEL_COLORS[struct.level];\n parts.push(formatter(`${struct.elapsed}/${struct.remaining}`));\n }\n }\n\n if (struct.chunks && struct.chunks.length) {\n parts.push(this.inspectChunks(struct.chunks));\n }\n\n if (struct.results) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter(JSON.stringify(struct.results, null, 4)));\n }\n\n return parts.join(\" \");\n }\n\n private inspectChunks(chunks: any[]): string {\n return chunks\n .map(chunk => util.inspect(chunk, { colors: true, depth: null }))\n .join(\" \");\n }\n\n private normalizeOptions(options: LoggerOptions): NormalizedOptions {\n const { route, mode, prefix, silent, showLevel, timestamp, levels, progress } = options;\n const normalized: NormalizedOptions = {\n mode: this.isValidMode(mode) ? mode! : \"text\",\n route: route ?? (typeof process.send === \"function\" ? \"ipc\" : \"console\"),\n prefix,\n silent: silent ?? false,\n showLevel: showLevel ?? true,\n timestamp: timestamp ?? false,\n levels: this.normalizeLevels(levels),\n progressTimes: progress?.withTimes ?? false,\n progressThrottle: progress?.throttleMs\n };\n return normalized;\n }\n\n private normalizeLevels(levels?: string[]): LevelName[] {\n if (!levels || !levels.length) {\n return ALL_LEVELS;\n }\n\n const includes = levels.filter(level => !level.startsWith(\"-\")) as LevelName[];\n const excludes = levels\n .filter(level => level.startsWith(\"-\"))\n .map(level => level.slice(1)) as LevelName[];\n\n const unknown = [...includes, ...excludes].filter(level => !ALL_LEVELS.includes(level));\n if (unknown.length) {\n console.warn(`[Logger] Unknown level(s): ${unknown.join(\", \")}`);\n }\n\n const base = includes.length ? includes : ALL_LEVELS;\n return base.filter(level => !excludes.includes(level));\n }\n\n private isValidMode(mode?: string | null): mode is LoggerMode | undefined {\n return mode === undefined || mode === null || mode === \"text\" || mode === \"json\";\n }\n\n private round(value: number, places: number): number {\n const factor = Math.pow(10, places);\n return Math.round(value * factor) / factor;\n }\n}\n\n\n","import { LoggerTransport } from \"./types.js\";\n\nexport class ConsoleTransport implements LoggerTransport {\n write(payload: any): void {\n console.info(payload);\n }\n}\n\nexport class ParentProcessTransport implements LoggerTransport {\n write(payload: any): void {\n if (typeof process.send === \"function\") {\n process.send(payload);\n } else {\n console.info(payload);\n }\n }\n}\n\n\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nmakarov/cli-toolkit",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A comprehensive toolkit for building CLI applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -36,6 +36,11 @@
36
36
  "types": "./dist/errors.d.ts",
37
37
  "import": "./dist/errors.js",
38
38
  "require": "./dist/errors.cjs"
39
+ },
40
+ "./logger": {
41
+ "types": "./dist/logger.d.ts",
42
+ "import": "./dist/logger.js",
43
+ "require": "./dist/logger.cjs"
39
44
  }
40
45
  },
41
46
  "scripts": {