jet-logger 2.2.3 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -0
- package/README.md +187 -5
- package/lib/index.d.ts +111 -0
- package/lib/index.js +12 -0
- package/package.json +43 -34
- package/dist/cjs/index.js +0 -1
- package/dist/cjs/jetLogger.js +0 -219
- package/dist/esm/index.js +0 -1
- package/dist/esm/jetLogger.js +0 -219
- package/dist/types/index.d.ts +0 -1
- package/dist/types/jetLogger.d.ts +0 -62
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -1,12 +1,194 @@
|
|
|
1
|
-
# Jet-Logger
|
|
1
|
+
# ✈️🪵 Jet-Logger
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> A super quick, easy to setup TypeScript first logging tool for NodeJS and browsers.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/jet-logger)
|
|
6
6
|
[](https://www.npmjs.com/package/jet-logger)
|
|
7
|
-
[](https://github.com/seanpmaxwell/jet-logger/blob/
|
|
7
|
+
[](https://github.com/seanpmaxwell/jet-logger/blob/main/LICENSE)
|
|
8
8
|
[](https://www.npmjs.com/package/jet-logger)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
<p align="center">· · ·</p>
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## 👀 Preview
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
<p align="center">· · ·</p>
|
|
17
|
+
|
|
18
|
+
## Features ✨
|
|
19
|
+
|
|
20
|
+
- Works locally and in browsers
|
|
21
|
+
- Zero dependencies, written in TypeScript
|
|
22
|
+
- Configure programmatically or through environment variables
|
|
23
|
+
- Tiny: **8 kB** packed
|
|
24
|
+
- Logs can be sent to the console or a file
|
|
25
|
+
- Both plain-text `line` and `json` (JSON Lines) formats supported
|
|
26
|
+
- Color-coded `info`, `imp`, `warn`, and `err` levels in terminals
|
|
27
|
+
|
|
28
|
+
<p align="center">· · ·</p>
|
|
29
|
+
|
|
30
|
+
## 📦 Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install jet-logger
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
> Requires Node.js 20.16+ or 22.3+. Jet-Logger is an ES module; CommonJS projects can `require()` it on Node.js 20.19+ and 22.12+.
|
|
37
|
+
|
|
38
|
+
<p align="center">· · ·</p>
|
|
39
|
+
|
|
40
|
+
## ⚡ Quick Start
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import logger from 'jet-logger';
|
|
44
|
+
|
|
45
|
+
logger.info('Server started on port', 3000);
|
|
46
|
+
logger.imp('Connected to the database');
|
|
47
|
+
logger.warn('Slow response:', { route: '/users', ms: 1200 });
|
|
48
|
+
logger.err('Payment failed:', 'card declined');
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
With the default options, that prints (colors not shown):
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
[14:03:21.045] INFO: hello jet-logger
|
|
55
|
+
[14:03:21.046] IMPORTANT: hello jet-logger
|
|
56
|
+
[14:03:21.046] WARNING: hello jet-logger
|
|
57
|
+
[14:03:21.046] ERROR: hello jet-logger
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The default export is a ready-made logger configured from environment variables. To create your own, call `JetLogger()`:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
import { JetLogger } from 'jet-logger';
|
|
64
|
+
|
|
65
|
+
const fileLogger = JetLogger({
|
|
66
|
+
mode: JetLogger.Modes.FILE,
|
|
67
|
+
filepath: './logs/app.log',
|
|
68
|
+
format: JetLogger.Formats.JSON,
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
fileLogger.info('Written to disk');
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
<p align="center">· · ·</p>
|
|
75
|
+
|
|
76
|
+
## 📘 Log Methods
|
|
77
|
+
|
|
78
|
+
| Method | Description |
|
|
79
|
+
| --------------- | ----------------------------------------------------------------------------------- |
|
|
80
|
+
| `info(...args)` | Log at `INFO` level |
|
|
81
|
+
| `imp(...args)` | Log at `IMPORTANT` level |
|
|
82
|
+
| `warn(...args)` | Log at `WARNING` level (stderr in console mode) |
|
|
83
|
+
| `err(...args)` | Log at `ERROR` level (stderr in console mode) |
|
|
84
|
+
| `out(...args)` | Print the arguments as their own line, without a label or timestamp |
|
|
85
|
+
| `line()` | Print an empty line |
|
|
86
|
+
| `catch(fn)` | Call `fn` and log its error message if it throws or returns a rejected promise |
|
|
87
|
+
| `flush()` | Returns a promise that resolves once everything logged so far has been written |
|
|
88
|
+
| `close()` | Flush, then release the log file. Later calls on this logger are ignored |
|
|
89
|
+
|
|
90
|
+
Arguments are joined with a space. Objects are printed in full (`util.inspect` in Node, JSON in the browser).
|
|
91
|
+
|
|
92
|
+
<p align="center">· · ·</p>
|
|
93
|
+
|
|
94
|
+
## ⚙️ Configuration
|
|
95
|
+
|
|
96
|
+
Every option can be passed to `JetLogger()` or set with an environment variable. Options passed in code take priority over environment variables, which take priority over the defaults.
|
|
97
|
+
|
|
98
|
+
| Option | Environment variable | Values | Default |
|
|
99
|
+
| ----------------------- | ------------------------------------- | ---------------------------------------------- | ---------------- |
|
|
100
|
+
| `mode` | `JET_LOGGER_MODE` | `console`, `file`, `browser`, `custom`, `off` | `console` |
|
|
101
|
+
| `format` | `JET_LOGGER_FORMAT` | `line`, `json` | `line` |
|
|
102
|
+
| `filepath` | `JET_LOGGER_FILEPATH` | Path of the log file (file mode) | `jet-logger.log` |
|
|
103
|
+
| `prependTimeToFilename` | `JET_LOGGER_PREPEND_TIME_TO_FILENAME` | `true`, `false` | `false` |
|
|
104
|
+
| `showTime` | `JET_LOGGER_SHOW_TIME` | `true`, `false` | `true` |
|
|
105
|
+
| `customTransport` | — | Your function (required when mode is `custom`) | — |
|
|
106
|
+
|
|
107
|
+
- `JetLogger.Modes` and `JetLogger.Formats` hold the mode and format values.
|
|
108
|
+
- Environment variables are read when a logger is created. The default logger is created the first time you use it, so variables set after importing (e.g. by a `.env` loader) still apply.
|
|
109
|
+
- Environment values are case-insensitive (except `JET_LOGGER_FILEPATH`); unrecognized values are ignored.
|
|
110
|
+
- Options set to `undefined` use the default. Invalid or unknown options throw an `InvalidOptionError`, which is exported.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### Output formats
|
|
115
|
+
|
|
116
|
+
`line` uses local time. The console shows just the time of day; files also include the date:
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
[14:03:21.045] WARNING: something happened <- console
|
|
120
|
+
[2026-09-24 14:03:21.045] WARNING: something happened <- file
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Colors are used only when the output is a terminal. Set `NO_COLOR` to turn them off or `FORCE_COLOR` to force them on.
|
|
124
|
+
|
|
125
|
+
`json` writes one object per line with an ISO timestamp in `time`. Text is joined into `msg`, objects go into `data` (an array if there are several), and the first `Error` adds its message to `msg` and its stack frames to `stack`:
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
logger.warn('payment failed:', new Error('card declined'), { orderId: 42 });
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{"time":"2026-09-25T01:04:01.247Z","level":"WARNING","msg":"payment failed: card declined","data":{"orderId":42},"stack":["at charge (/app/pay.js:10:11)"]}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`line` prints messages as-is, so text from users could add fake log lines or terminal escape codes. Use `json` for untrusted input; its values are escaped.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### File mode
|
|
140
|
+
|
|
141
|
+
- Logs are appended to `filepath`. Missing directories are created automatically.
|
|
142
|
+
- Loggers writing to the same file share it, so their lines stay in order.
|
|
143
|
+
- Lines logged in the same tick are written together in one synchronous write at the end of the tick, or as soon as 64 KB are waiting, so memory use stays small even when logging in bursts.
|
|
144
|
+
- Anything not yet written is flushed when the process exits, crashes, or receives `SIGINT` or `SIGTERM`. If your app handles those signals itself, jet-logger flushes and leaves exiting to your handler.
|
|
145
|
+
- `await logger.flush()` makes sure everything is on disk; `await logger.close()` also closes the file.
|
|
146
|
+
- `prependTimeToFilename` starts a new file each run: `logs/app.log` → `logs/20260925T010401Z_app.log`.
|
|
147
|
+
- With the `json` format, the default file name becomes `jet-logger.jsonl`.
|
|
148
|
+
- Files are created with your process's default permissions, which usually lets other users read them. Use a stricter `umask` or directory if your logs hold sensitive data.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
### Browser
|
|
153
|
+
|
|
154
|
+
In browsers and web workers, `console` and `file` modes switch to `browser` mode automatically, which prints styled logs with `console.info`, `console.warn`, and `console.error`.
|
|
155
|
+
|
|
156
|
+
<p align="center">· · ·</p>
|
|
157
|
+
|
|
158
|
+
## 🚚 Custom Transports
|
|
159
|
+
|
|
160
|
+
Set `mode` to `custom` to send every log to your own function, e.g. to forward it to Datadog, Splunk, or an HTTP collector:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
import { JetLogger, type CustomTransportFn } from 'jet-logger';
|
|
164
|
+
|
|
165
|
+
const sendToSplunk: CustomTransportFn = async ({ time, level, msg }) => {
|
|
166
|
+
await splunkClient.emit({ time, level, msg });
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const remoteLogger = JetLogger({
|
|
170
|
+
mode: JetLogger.Modes.CUSTOM,
|
|
171
|
+
customTransport: sendToSplunk,
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
remoteLogger.imp('Sent to Splunk');
|
|
175
|
+
await remoteLogger.flush(); // e.g. before exiting: waits for pending sends
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The function can be async. If it throws or its promise rejects, the error is reported on stderr (`console.error` in browsers) instead of crashing your app.
|
|
179
|
+
|
|
180
|
+
It receives a `CustomTransportContext`:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
interface CustomTransportContext {
|
|
184
|
+
time: string; // ISO 8601
|
|
185
|
+
level: 'INFO' | 'IMPORTANT' | 'WARNING' | 'ERROR' | null; // null for out() and line()
|
|
186
|
+
msg: string; // all arguments joined into one string
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
<p align="center">· · ·</p>
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
[MIT](./LICENSE) © seanpmaxwell
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
2
|
+
|
|
3
|
+
type BaseTypes = Record<string, number> | Record<string, string>;
|
|
4
|
+
type Enum<O extends BaseTypes> = {
|
|
5
|
+
[K in keyof O]: O[K] extends string | number ? O[K] : never;
|
|
6
|
+
}[keyof O];
|
|
7
|
+
interface EnumUtils<T> {
|
|
8
|
+
is: (val: unknown) => val is T[keyof T];
|
|
9
|
+
table: () => T;
|
|
10
|
+
}
|
|
11
|
+
type EnumTable<T> = T extends EnumUtils<infer P> ? P : never;
|
|
12
|
+
declare const ModesTable: {
|
|
13
|
+
readonly CONSOLE: "console";
|
|
14
|
+
readonly FILE: "file";
|
|
15
|
+
readonly BROWSER: "browser";
|
|
16
|
+
readonly CUSTOM: "custom";
|
|
17
|
+
readonly OFF: "off";
|
|
18
|
+
};
|
|
19
|
+
type ModesTable = typeof ModesTable;
|
|
20
|
+
declare const Modes: {
|
|
21
|
+
readonly is: (val: unknown) => val is "console" | "file" | "browser" | "custom" | "off";
|
|
22
|
+
readonly table: () => {
|
|
23
|
+
readonly CONSOLE: "console";
|
|
24
|
+
readonly FILE: "file";
|
|
25
|
+
readonly BROWSER: "browser";
|
|
26
|
+
readonly CUSTOM: "custom";
|
|
27
|
+
readonly OFF: "off";
|
|
28
|
+
};
|
|
29
|
+
readonly CONSOLE: "console";
|
|
30
|
+
readonly FILE: "file";
|
|
31
|
+
readonly BROWSER: "browser";
|
|
32
|
+
readonly CUSTOM: "custom";
|
|
33
|
+
readonly OFF: "off";
|
|
34
|
+
};
|
|
35
|
+
type Modes = Enum<ModesTable>;
|
|
36
|
+
declare const FormatsTable: {
|
|
37
|
+
readonly LINE: "line";
|
|
38
|
+
readonly JSON: "json";
|
|
39
|
+
};
|
|
40
|
+
type FormatsTable = typeof FormatsTable;
|
|
41
|
+
declare const Formats: {
|
|
42
|
+
readonly is: (val: unknown) => val is "line" | "json";
|
|
43
|
+
readonly table: () => {
|
|
44
|
+
readonly LINE: "line";
|
|
45
|
+
readonly JSON: "json";
|
|
46
|
+
};
|
|
47
|
+
readonly LINE: "line";
|
|
48
|
+
readonly JSON: "json";
|
|
49
|
+
};
|
|
50
|
+
type Formats = Enum<FormatsTable>;
|
|
51
|
+
type Labels = "INFO" | "WARNING" | "ERROR" | "IMPORTANT";
|
|
52
|
+
type IOptions = {
|
|
53
|
+
format: Formats;
|
|
54
|
+
showTime: boolean;
|
|
55
|
+
prependTimeToFilename: boolean;
|
|
56
|
+
filepath: string;
|
|
57
|
+
} & ({
|
|
58
|
+
mode: Exclude<Modes, "custom">;
|
|
59
|
+
customTransport: null;
|
|
60
|
+
} | {
|
|
61
|
+
mode: Modes;
|
|
62
|
+
customTransport: CustomTransportFn;
|
|
63
|
+
});
|
|
64
|
+
export interface CustomTransportContext {
|
|
65
|
+
time: string;
|
|
66
|
+
level: Labels | null;
|
|
67
|
+
msg: string;
|
|
68
|
+
}
|
|
69
|
+
export interface CustomTransportFn {
|
|
70
|
+
(context: CustomTransportContext): void | Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
type APIOptions = Partial<IOptions>;
|
|
73
|
+
export type JetLoggerOptions = APIOptions;
|
|
74
|
+
export type JetLoggerInstance = Readonly<{
|
|
75
|
+
info(...args: unknown[]): void;
|
|
76
|
+
warn(...args: unknown[]): void;
|
|
77
|
+
err(...args: unknown[]): void;
|
|
78
|
+
imp(...args: unknown[]): void;
|
|
79
|
+
line(): void;
|
|
80
|
+
out(...args: unknown[]): void;
|
|
81
|
+
catch(cb: () => unknown): void;
|
|
82
|
+
flush(): Promise<void>;
|
|
83
|
+
close(): Promise<void>;
|
|
84
|
+
}>;
|
|
85
|
+
/**
|
|
86
|
+
* Throw this when the property on an object is invalid.
|
|
87
|
+
*/
|
|
88
|
+
declare class InvalidOptionErr extends Error {
|
|
89
|
+
readonly property: string;
|
|
90
|
+
readonly value: unknown;
|
|
91
|
+
protected constructor(message: string, property: string, value: unknown);
|
|
92
|
+
/**
|
|
93
|
+
* Factory-Function. Setup the message and return a new instance.
|
|
94
|
+
*/
|
|
95
|
+
static of(property: string, value: unknown, additionalMsg?: string): InvalidOptionErr;
|
|
96
|
+
}
|
|
97
|
+
interface JetLogger {
|
|
98
|
+
(options?: JetLoggerOptions): JetLoggerInstance;
|
|
99
|
+
readonly Modes: EnumTable<typeof Modes>;
|
|
100
|
+
readonly Formats: EnumTable<typeof Formats>;
|
|
101
|
+
}
|
|
102
|
+
declare const DefaultLogger: JetLoggerInstance;
|
|
103
|
+
declare const JetLogger$1: JetLogger;
|
|
104
|
+
|
|
105
|
+
export {
|
|
106
|
+
DefaultLogger as default,
|
|
107
|
+
InvalidOptionErr as InvalidOptionError,
|
|
108
|
+
JetLogger$1 as JetLogger,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export {};
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
function gt(t){return typeof t=="boolean"}function ht(t){return typeof t=="number"}function wt(t){return typeof t=="string"}function St(t){return typeof t=="string"&&t.length>0}function yt(t){return t!==void 0}function Tt(t){return typeof t=="object"&&t!==null}function Et(t){return typeof t=="function"}function bt(t){return t===null||typeof t=="function"}function Ot(t){if(typeof t=="boolean")return t;if(typeof t=="string"){let e=t.toLowerCase();if(e==="true")return!0;if(e==="false")return!1}}var c={is:{def:yt,bool:gt,num:ht,str:wt,neStr:St,obj:Tt,fn:Et,nul:{fn:bt}},parse:{bool:Ot}};function v(t){let e=Object.values(t);e=e.filter(n=>c.is.str(n)||c.is.num(n));let o=new Set(e);return{is:n=>o.has(n),table:()=>({...t})}}var H={CONSOLE:"console",FILE:"file",BROWSER:"browser",CUSTOM:"custom",OFF:"off"},p={...H,...v(H)},Y={LINE:"line",JSON:"json"},f={...Y,...v(Y)};var K=/^\s+at /;function M(t){return t instanceof Error?t.message:String(t)}function z(t){if(!t.stack)return;let e=t.stack.split(`
|
|
2
|
+
`),o=e.findIndex(n=>K.test(n));return(o>=0?e.slice(o):e).map(n=>n.trim()).filter(n=>n!=="")}function O(t){let e=String(t),{stack:o}=t;return o?o.startsWith(e)||o.split(`
|
|
3
|
+
`).some(r=>K.test(r))?o:`${e}
|
|
4
|
+
${o}`:e}function Lt(t,e,o){let r=i=>{try{e(i)}catch{}},n;try{n=t()}catch(i){return r(i)}if(!Ft(n))return;let s=Promise.resolve(n).then(void 0,r).finally(()=>o?.delete(s));o?.add(s)}function Ft(t){return(typeof t=="object"||typeof t=="function")&&t!==null&&typeof t.then=="function"}var b=Lt;function xt(t,e){let o=[],r=function(n,s){for(;o.length>0&&o[o.length-1].holder!==this;)o.pop();if(typeof s=="bigint")return`${s}n`;if(typeof s!="object"||s===null)return s;if(o.some(l=>l.original===s))return"[Circular]";let i=kt(s);return o.push({holder:i,original:s}),i};try{return JSON.stringify(t,r,e)??String(t)}catch{return String(t)}}function kt(t){return t instanceof Error?{name:t.name,message:t.message,stack:t.stack}:t instanceof Map||t instanceof Set?Array.from(t):t}var L=xt;var It="Node.js built-in modules aren't available in this environment";function Rt(){let t=globalThis.process;if(typeof t?.getBuiltinModule!="function")return{IS_BROWSER:!0,IS_LOCAL:!1,nodeModules:()=>{throw new Error(It)}};let e={fs:t.getBuiltinModule("fs"),path:t.getBuiltinModule("path"),util:t.getBuiltinModule("util")};return{IS_BROWSER:!1,IS_LOCAL:!0,nodeModules:()=>e}}var u=Rt();var Pt=(()=>{if(u.IS_LOCAL){let{util:t}=u.nodeModules();return(e,o)=>t.inspect(e,{depth:null,colors:o})}return t=>t instanceof Error?O(t):L(t,2)})(),V=Pt;function vt(t,e){return t.map(o=>c.is.str(o)?o:c.is.obj(o)?V(o,e):String(o)).join(" ")}var m=vt;var Mt={Green:{SGR:"32",CSS:"color: #008000"},LightGreen:{SGR:"2;32",CSS:"color: #006B00"},Yellow:{SGR:"33",CSS:"color: #DAA520"},Red:{SGR:"31",CSS:"color: #FF0000"},Magenta:{SGR:"35",CSS:"color: #FF00FF"},White:{SGR:"38;5;248",CSS:"color: #808080"}},w=Mt;var Ct={Bold:{SGR:"1",CSS:"font-weight: bold"},Underline:{SGR:"4",CSS:"text-decoration: underline"}},C=Ct;var X="\x1B[0m",F=S(w.LightGreen),x=S(w.White),y={Info:{label:"INFO",consoleFn:"info",...S(w.Green)},Important:{label:"IMPORTANT",consoleFn:"info",...S(w.Magenta,C.Bold,C.Underline)},Warning:{label:"WARNING",consoleFn:"warn",...S(w.Yellow)},Error:{label:"ERROR",consoleFn:"error",...S(w.Red)}};function S(...t){return{ansi:`\x1B[${t.map(e=>e.SGR).join(";")}m`,css:t.map(e=>e.CSS).join("; ")}}var k=t=>t,q=(t,e)=>`${e.ansi}${t}${X}`;function I(t,e){let{level:o,args:r}=t,{showTime:n,showDate:s,paint:i}=e,l=i(o.label,o),a=i(m(r,!1),x);return n?`${i(N(s),F)} ${l}: ${a}`:`${l}: ${a}`}function N(t,e=new Date){let o=T(e.getHours()),r=T(e.getMinutes()),n=T(e.getSeconds()),s=T(e.getMilliseconds(),3),i=`${o}:${r}:${n}.${s}`;if(!t)return`[${i}]`;let l=e.getFullYear(),a=T(e.getMonth()+1),h=T(e.getDate());return`[${l}-${a}-${h} ${i}]`}function T(t,e=2){return String(t).padStart(e,"0")}function E(t,e){let o=[],r=[],n;for(let a of t.args)a instanceof Error&&!n?(n=a,o.push(a.message)):typeof a=="object"&&a!==null?r.push(a):o.push(String(a));let s=t.level.label,i=o.join(" "),l=e?{time:new Date().toISOString(),level:s,msg:i}:{level:s,msg:i};return r.length>0&&(l.data=r.length===1?r[0]:r),n&&(l.stack=z(n)),L(l)}function Q(t,e){let o=e instanceof Error?O(e):String(e),r=`jet-logger: ${t}: ${o}`;u.IS_LOCAL?process.stderr.write(r+`
|
|
5
|
+
`):console.error(r)}var A=class t{#t;constructor(e){this.#t=e}static of(e){let{format:o,showTime:r}=e;return o===f.JSON?new t(n=>["%s",E(n,r)]):new t(n=>Nt(n,r))}writeLog(e){let o=this.#t(e);console[e.level.consoleFn](...o)}writeRaw(e){let o=m(e,!1);console.info("%s",o)}flush(){return Promise.resolve()}close(){return Promise.resolve()}};function Nt(t,e){let{level:o,args:r}=t,n=m(r,!1),s=[o.css,o.label,x.css,n];return e?["%c%s %c%s: %c%s",...[F.css,N(!1)],...s]:["%c%s: %c%s",...s]}var Z=A;var J=class t{#t;#e;#o;constructor(e){this.#t=e,this.#e=tt(process.stdout),this.#o=tt(process.stderr)}static of(e){let{format:o,showTime:r}=e;return o===f.JSON?new t(n=>E(n,r)):new t((n,s)=>I(n,{showTime:r,showDate:!1,paint:s?q:k}))}writeLog(e){if(e.level.consoleFn==="info"){let o=this.#t(e,this.#e);process.stdout.write(o+`
|
|
6
|
+
`)}else{let o=this.#t(e,this.#o);process.stderr.write(o+`
|
|
7
|
+
`)}}writeRaw(e){let o=m(e,this.#e);process.stdout.write(o+`
|
|
8
|
+
`)}async flush(){let e=et(process.stdout),o=et(process.stderr);await Promise.all([e,o])}close(){return this.flush()}};function tt(t){let{FORCE_COLOR:e,NO_COLOR:o}=process.env;if(e!==void 0){let r=e.toLowerCase();return!["0","false"].includes(r)}return o?!1:t.isTTY===!0&&(t.hasColors?.()??!0)}function et(t){return new Promise(e=>t.write("",()=>e()))}var ot=J;function At(t,e){let{path:o}=u.nodeModules(),r=o.parse(t);return o.format({...r,base:void 0,ext:"."+e})}var nt=At;function Jt(t,e=new Date){let{path:o}=u.nodeModules(),r=o.parse(t),n=`${_t(e)}_${r.base}`;return o.format({...r,base:n})}function _t(t){return t.toISOString().replace(/[-:]/g,"").replace(/\.\d{3}/,"")}var rt=Jt;var _="jet-logger.log",R=()=>({mode:p.CONSOLE,format:f.LINE,filepath:_,prependTimeToFilename:!1,showTime:!0,customTransport:null});var Wt=["SIGINT","SIGTERM"],st=!1,W=new Set;function it(t){W.add(t),!st&&(st=!0,process.on("exit",at),Wt.forEach(e=>process.on(e,lt)))}function lt(t){at(),!(process.listenerCount(t)>1)&&(process.off(t,lt),process.kill(process.pid,t))}function at(){W.forEach(t=>t.flushSync())}function ut(t){W.delete(t)}var Gt=1e3;function jt(t,e){let{fs:o}=u.nodeModules(),r=0;for(;e.length>0;)try{e=e.subarray(o.writeSync(t,e)),r=0}catch(n){if(!(n.code==="EAGAIN")||++r>Gt)throw n;Bt(1)}}function Bt(t){Atomics.wait(new Int32Array(new SharedArrayBuffer(4)),0,0,t)}var ct=jt;var $t=2,Dt=64*1024,G=new Map,j=class t{#t;#e;#o="";#n;#r=0;constructor(e,o){this.#t=e,this.#e=o}static open(e){let{fs:o,path:r}=u.nodeModules(),n=r.resolve(e),s=G.get(n);if(!s){o.mkdirSync(r.dirname(n),{recursive:!0});let i=o.openSync(n,"a");s=new t(n,i),G.set(n,s),it(s)}return s.#r++,s}write(e){this.#o+=e,this.#o.length>=Dt?this.flushSync():this.#n??=setImmediate(()=>this.flushSync())}flush(){return this.flushSync(),Promise.resolve()}flushSync(){if(this.#n&&(clearImmediate(this.#n),this.#n=void 0),this.#o.length===0)return;let e=this.#o;this.#o="",Ut(this.#e,e)}async release(){await this.flush(),this.#r--,!(this.#r>0)&&(G.delete(this.#t),ut(this),u.nodeModules().fs.closeSync(this.#e))}};function Ut(t,e){try{ct(t,Buffer.from(e,"utf8"))}catch(o){Ht(o)}}function Ht(t){let e=t instanceof Error?t.message:String(t);try{u.nodeModules().fs.writeSync($t,`jet-logger: file write failed: ${e}
|
|
9
|
+
`)}catch{}}var ft=j;var B=class t{#t;#e;constructor(e,o){this.#t=e,this.#e=o}static of(e){let{format:o,showTime:r}=e,n=Yt(e),s=ft.open(n);return o===f.JSON?new t(s,i=>E(i,r)):new t(s,i=>I(i,{showTime:r,showDate:!0,paint:k}))}writeLog(e){this.#t.write(this.#e(e)+`
|
|
10
|
+
`)}writeRaw(e){this.#t.write(m(e,!1)+`
|
|
11
|
+
`)}flush(){return this.#t.flush()}close(){return this.#t.release()}};function Yt(t){let{filepath:e}=t;return t.format===f.JSON&&Kt(e)&&(e=nt(e,"jsonl")),t.prependTimeToFilename&&(e=rt(e)),e}function Kt(t){let{path:e}=u.nodeModules();return e.basename(t)===_}var pt=B;function zt(){let t=globalThis.process?.env;if(!t)return{};let{JET_LOGGER_MODE:e,JET_LOGGER_FILEPATH:o,JET_LOGGER_PREPEND_TIME_TO_FILENAME:r,JET_LOGGER_SHOW_TIME:n,JET_LOGGER_FORMAT:s}=t,i={},l=e?.toLowerCase();p.is(l)&&(i.mode=l),c.is.neStr(o)&&(i.filepath=o);let a=c.parse.bool(r);c.is.def(a)&&(i.prependTimeToFilename=a);let h=c.parse.bool(n);c.is.def(h)&&(i.showTime=h);let U=s?.toLowerCase();return f.is(U)&&(i.format=U),i}var mt=zt;var $=class t extends Error{property;value;constructor(e,o,r){super(e),this.name="InvalidOptionError",this.property=o,this.value=r}static of(e,o,r){let n=`Invalid option "${e}": ${Vt(o)}`;return r&&(n+=`. ${r}`),new t(n,e,o)}};function Vt(t){if(typeof t=="function")return`[Function ${t.name||"anonymous"}]`;try{return JSON.stringify(t)??String(t)}catch{return String(t)}}var d=$;var Xt='The mode is set to "custom". The "customTransport" must be a valid function type.',qt=Object.keys(R()),Qt=new Set(qt);function Zt(t){if(typeof t!="object"||t===null)throw d.of("options",t);for(let[l,a]of Object.entries(t))if(!Qt.has(l))throw d.of(l,a,"Unknown option");let{mode:e,format:o,showTime:r,prependTimeToFilename:n,filepath:s,customTransport:i}=t;if(!p.is(e))throw d.of("mode",e);if(!f.is(o))throw d.of("format",o);if(!c.is.bool(r))throw d.of("showTime",r);if(!c.is.bool(n))throw d.of("prependTimeToFilename",n);if(!c.is.neStr(s))throw d.of("filepath",s);if(!c.is.nul.fn(i))throw d.of("customTransport",i);if(e===p.CUSTOM&&!c.is.fn(i))throw d.of("customTransport",i,Xt)}var dt=Zt;function te(t){let e={...R(),...mt(),...se(t)};return dt(e),e.mode===p.OFF?ne():e.mode===p.CUSTOM?re(e.customTransport):ee(e)}function ee(t){let e=oe(t),o=new Set,r=!1,n,s=(i,l)=>{r||e.writeLog({level:i,args:l})};return{info:(...i)=>s(y.Info,i),warn:(...i)=>s(y.Warning,i),imp:(...i)=>s(y.Important,i),err:(...i)=>s(y.Error,i),line:()=>{r||e.writeRaw([])},out:(...i)=>{r||e.writeRaw(i)},catch:i=>{b(i,a=>s(y.Error,[M(a)]),o)},flush:async()=>{await P(o),await e.flush()},close:()=>n??=(async()=>{await P(o),r=!0,await e.close()})()}}function oe(t){return u.IS_BROWSER||t.mode===p.BROWSER?Z.of(t):t.mode===p.FILE?pt.of(t):ot.of(t)}function ne(){let t=()=>{};return{info:t,warn:t,imp:t,err:t,line:t,out:t,catch:e=>b(e,t),flush:()=>Promise.resolve(),close:()=>Promise.resolve()}}function re(t){let e=new Set,o=!1,r,n=(s,i)=>{if(o)return;let l={time:new Date().toISOString(),level:s,msg:m(i,!1)};b(()=>t(l),h=>Q("customTransport failed",h),e)};return{info:(...s)=>n("INFO",s),warn:(...s)=>n("WARNING",s),imp:(...s)=>n("IMPORTANT",s),err:(...s)=>n("ERROR",s),line:()=>n(null,[`
|
|
12
|
+
`]),out:(...s)=>n(null,s),catch:s=>{b(s,l=>n("ERROR",[M(l)]),e)},flush:()=>P(e),close:()=>r??=P(e).then(()=>{o=!0})}}function se(t){if(!t)return{};let e=Object.entries(t).filter(([,o])=>o!==void 0);return Object.fromEntries(e)}async function P(t){for(;t.size>0;)await Promise.all(t)}var D=te;var ie=Object.assign(D,{Modes:p.table(),Formats:f.table()}),le,g=()=>le??=D(),ae=Object.freeze({info:(...t)=>g().info(...t),warn:(...t)=>g().warn(...t),err:(...t)=>g().err(...t),imp:(...t)=>g().imp(...t),line:()=>g().line(),out:(...t)=>g().out(...t),catch:t=>g().catch(t),flush:()=>g().flush(),close:()=>g().close()}),Do=ie,Uo=ae;export{d as InvalidOptionError,Do as JetLogger,Uo as default};
|
package/package.json
CHANGED
|
@@ -1,31 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jet-logger",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A super quick, easy to setup logging tool for NodeJS
|
|
3
|
+
"version": "3.0.1",
|
|
4
|
+
"description": "A super quick, easy to setup TypeScript first logging tool for NodeJS and browsers.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "
|
|
7
|
-
"
|
|
8
|
-
"browser": "./dist/esm/index.js",
|
|
9
|
-
"types": "./dist/types/index.d.ts",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
10
8
|
"exports": {
|
|
11
9
|
".": {
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"types": "./dist/types/index.d.ts"
|
|
10
|
+
"types": "./lib/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
15
12
|
}
|
|
16
13
|
},
|
|
17
14
|
"files": [
|
|
18
|
-
"
|
|
15
|
+
"lib"
|
|
19
16
|
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=20.16.0 <21 || >=22.3.0"
|
|
19
|
+
},
|
|
20
20
|
"scripts": {
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
21
|
+
"benchmark": "tsx scripts/benchmark.ts",
|
|
22
|
+
"build": "tsx scripts/build.ts",
|
|
23
|
+
"commit": "npm run format && git add -A && git commit -m \"dev commit\"",
|
|
24
|
+
"commit:push": "npm run commit && git push",
|
|
25
|
+
"demo:gif": "bash demo-studio/start.sh",
|
|
26
|
+
"install:clean": "rm -rf node_modules && rm -f package-lock.json && npm i",
|
|
27
|
+
"lint": "eslint . --max-warnings 0",
|
|
28
|
+
"lint:fix": "eslint . --fix",
|
|
29
|
+
"format": "prettier --write .",
|
|
30
|
+
"format:check": "prettier --check .",
|
|
31
|
+
"npm-data": "npm run build && npm pack --dry-run --json",
|
|
32
|
+
"prepublishOnly": "npm run build && tsc && npm run lint && npm run format:check && npm test && npm run test:browser && npm run verify:package",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:browser": "vitest run --config vitest.browser.config.ts",
|
|
35
|
+
"typecheck": "tsc",
|
|
36
|
+
"verify:package": "tsx scripts/verifyPackage.ts"
|
|
29
37
|
},
|
|
30
38
|
"repository": {
|
|
31
39
|
"type": "git",
|
|
@@ -58,23 +66,24 @@
|
|
|
58
66
|
"url": "https://github.com/seanpmaxwell/jet-logger/issues"
|
|
59
67
|
},
|
|
60
68
|
"homepage": "https://github.com/seanpmaxwell/jet-logger#readme",
|
|
61
|
-
"dependencies": {
|
|
62
|
-
"colors": "1.4.0"
|
|
63
|
-
},
|
|
64
69
|
"devDependencies": {
|
|
65
|
-
"@eslint/js": "^
|
|
66
|
-
"@
|
|
67
|
-
"@
|
|
68
|
-
"@
|
|
69
|
-
"
|
|
70
|
+
"@eslint/js": "^10.0.1",
|
|
71
|
+
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
|
72
|
+
"@types/node": "^20.19.43",
|
|
73
|
+
"@vitest/browser": "^4.1.11",
|
|
74
|
+
"@vitest/browser-playwright": "^4.1.11",
|
|
75
|
+
"chalk": "^6.0.0",
|
|
76
|
+
"dts-bundle-generator": "^9.5.1",
|
|
77
|
+
"esbuild": "^0.28.2",
|
|
78
|
+
"eslint": "^10.7.0",
|
|
70
79
|
"eslint-config-prettier": "^10.1.8",
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"prettier": "^3.
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"typescript-eslint": "^8.
|
|
78
|
-
"vitest": "^4.
|
|
80
|
+
"globals": "^17.7.0",
|
|
81
|
+
"jiti": "^2.7.0",
|
|
82
|
+
"playwright": "^1.63.0",
|
|
83
|
+
"prettier": "^3.9.5",
|
|
84
|
+
"tsx": "^4.23.11",
|
|
85
|
+
"typescript": "^6.0.3",
|
|
86
|
+
"typescript-eslint": "^8.65.0",
|
|
87
|
+
"vitest": "^4.1.10"
|
|
79
88
|
}
|
|
80
89
|
}
|
package/dist/cjs/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { JetLogger, jetLogger, default, } from './jetLogger.js';
|
package/dist/cjs/jetLogger.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import colors from 'colors';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import util from 'util';
|
|
4
|
-
const Modes = {
|
|
5
|
-
CONSOLE: 'console',
|
|
6
|
-
FILE: 'file',
|
|
7
|
-
CUSTOM: 'custom',
|
|
8
|
-
OFF: 'off',
|
|
9
|
-
};
|
|
10
|
-
const Formats = {
|
|
11
|
-
LINE: 'line',
|
|
12
|
-
JSON: 'json',
|
|
13
|
-
};
|
|
14
|
-
const Levels = {
|
|
15
|
-
Info: {
|
|
16
|
-
COLOR: 'green',
|
|
17
|
-
PREFIX: 'INFO',
|
|
18
|
-
},
|
|
19
|
-
Important: {
|
|
20
|
-
COLOR: 'magenta',
|
|
21
|
-
PREFIX: 'IMPORTANT',
|
|
22
|
-
},
|
|
23
|
-
Warning: {
|
|
24
|
-
COLOR: 'yellow',
|
|
25
|
-
PREFIX: 'WARNING',
|
|
26
|
-
},
|
|
27
|
-
Error: {
|
|
28
|
-
COLOR: 'red',
|
|
29
|
-
PREFIX: 'ERROR',
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
const Defaults = {
|
|
33
|
-
MODE: Modes.CONSOLE,
|
|
34
|
-
FILE_PATH: 'jet-logger.log',
|
|
35
|
-
TIMESTAMP: true,
|
|
36
|
-
FORMAT: Formats.LINE,
|
|
37
|
-
CUSTOM_LOGGER_FUNCTION: () => ({}),
|
|
38
|
-
};
|
|
39
|
-
const Errors = {
|
|
40
|
-
CUSTOM_LOGGER: 'Custom logger mode set to true, but no custom logger was provided.',
|
|
41
|
-
MODE: 'The correct logger mode was not specified: Must be "custom", "file", ' +
|
|
42
|
-
'"off", or "console".',
|
|
43
|
-
};
|
|
44
|
-
export const JetLogger = {
|
|
45
|
-
Modes,
|
|
46
|
-
Formats,
|
|
47
|
-
};
|
|
48
|
-
export function jetLogger(options) {
|
|
49
|
-
let mode = Defaults.MODE, filePath = Defaults.FILE_PATH, timestamp = Defaults.TIMESTAMP, format = Defaults.FORMAT, customLogFn = Defaults.CUSTOM_LOGGER_FUNCTION;
|
|
50
|
-
if (options?.mode !== undefined) {
|
|
51
|
-
mode = options.mode;
|
|
52
|
-
}
|
|
53
|
-
else if (!!process.env.JET_LOGGER_MODE) {
|
|
54
|
-
mode = process.env.JET_LOGGER_MODE.toLowerCase();
|
|
55
|
-
}
|
|
56
|
-
if (mode === Modes.OFF) {
|
|
57
|
-
return {
|
|
58
|
-
info: (_, __) => ({}),
|
|
59
|
-
imp: (_, __) => ({}),
|
|
60
|
-
warn: (_, __) => ({}),
|
|
61
|
-
err: (_, __) => ({}),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
if (mode === Modes.CUSTOM) {
|
|
65
|
-
if (options?.customLogger !== undefined) {
|
|
66
|
-
customLogFn = options.customLogger;
|
|
67
|
-
}
|
|
68
|
-
if (!customLogFn) {
|
|
69
|
-
throw Error(Errors.CUSTOM_LOGGER);
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
info: setupPrintWithCustomLogger(Levels.Info, customLogFn),
|
|
73
|
-
imp: setupPrintWithCustomLogger(Levels.Important, customLogFn),
|
|
74
|
-
warn: setupPrintWithCustomLogger(Levels.Warning, customLogFn),
|
|
75
|
-
err: setupPrintWithCustomLogger(Levels.Error, customLogFn),
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
if (options?.filepath !== undefined) {
|
|
79
|
-
filePath = options.filepath;
|
|
80
|
-
}
|
|
81
|
-
else if (!!process.env.JET_LOGGER_FILEPATH) {
|
|
82
|
-
filePath = process.env.JET_LOGGER_FILEPATH;
|
|
83
|
-
}
|
|
84
|
-
if (options?.timestamp !== undefined) {
|
|
85
|
-
timestamp = options.timestamp;
|
|
86
|
-
}
|
|
87
|
-
else if (!!process.env.JET_LOGGER_TIMESTAMP) {
|
|
88
|
-
const envVar = process.env.JET_LOGGER_TIMESTAMP;
|
|
89
|
-
timestamp = envVar.toLowerCase() === 'true';
|
|
90
|
-
}
|
|
91
|
-
if (options?.format !== undefined) {
|
|
92
|
-
format = options.format;
|
|
93
|
-
}
|
|
94
|
-
else if (!!process.env.JET_LOGGER_FORMAT) {
|
|
95
|
-
format = process.env.JET_LOGGER_FORMAT.toLowerCase();
|
|
96
|
-
}
|
|
97
|
-
let formatter = () => '';
|
|
98
|
-
if (format === Formats.LINE) {
|
|
99
|
-
formatter = setupLineFormatter(timestamp);
|
|
100
|
-
}
|
|
101
|
-
else if (format === Formats.JSON) {
|
|
102
|
-
formatter = setupJsonFormatter(timestamp);
|
|
103
|
-
}
|
|
104
|
-
if (mode === Modes.FILE) {
|
|
105
|
-
let filePathDatetime = true;
|
|
106
|
-
if (options?.filepathDatetimeParam !== undefined) {
|
|
107
|
-
filePathDatetime = options.filepathDatetimeParam;
|
|
108
|
-
}
|
|
109
|
-
else if (!!process.env.JET_LOGGER_FILEPATH_DATETIME) {
|
|
110
|
-
const envVar = process.env.JET_LOGGER_FILEPATH_DATETIME;
|
|
111
|
-
filePathDatetime = envVar.toLowerCase() === 'true';
|
|
112
|
-
}
|
|
113
|
-
if (filePathDatetime) {
|
|
114
|
-
filePath = addDatetimeToFileName(filePath);
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
info: setupPrintToFile(Levels.Info, formatter, filePath),
|
|
118
|
-
imp: setupPrintToFile(Levels.Important, formatter, filePath),
|
|
119
|
-
warn: setupPrintToFile(Levels.Warning, formatter, filePath),
|
|
120
|
-
err: setupPrintToFile(Levels.Error, formatter, filePath),
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
info: setupPrintToConsole(Levels.Info, formatter),
|
|
125
|
-
imp: setupPrintToConsole(Levels.Important, formatter),
|
|
126
|
-
warn: setupPrintToConsole(Levels.Warning, formatter),
|
|
127
|
-
err: setupPrintToConsole(Levels.Error, formatter),
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
function setupPrintWithCustomLogger(level, customLogFn) {
|
|
131
|
-
return (content, printFull) => {
|
|
132
|
-
let contentNew;
|
|
133
|
-
if (printFull) {
|
|
134
|
-
contentNew = util.inspect(content);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
contentNew = String(content);
|
|
138
|
-
}
|
|
139
|
-
return customLogFn(new Date(), level.PREFIX, contentNew);
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
function setupLineFormatter(timestamp) {
|
|
143
|
-
if (timestamp) {
|
|
144
|
-
return (content, level) => {
|
|
145
|
-
const contentNew = level.PREFIX + ': ' + content, time = '[' + new Date().toISOString() + '] ';
|
|
146
|
-
return time + contentNew;
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
return (content, level) => {
|
|
151
|
-
return level.PREFIX + ': ' + content;
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
function setupJsonFormatter(timestamp) {
|
|
156
|
-
if (timestamp) {
|
|
157
|
-
return (content, level) => {
|
|
158
|
-
const json = {
|
|
159
|
-
level: level.PREFIX,
|
|
160
|
-
message: content,
|
|
161
|
-
};
|
|
162
|
-
json.timestamp = new Date().toISOString();
|
|
163
|
-
return JSON.stringify(json);
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
return (content, level) => {
|
|
168
|
-
const json = {
|
|
169
|
-
level: level.PREFIX,
|
|
170
|
-
message: content,
|
|
171
|
-
};
|
|
172
|
-
return JSON.stringify(json);
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
function setupPrintToFile(level, formatter, filePath) {
|
|
177
|
-
return (content, printFull) => {
|
|
178
|
-
let contentNew;
|
|
179
|
-
if (!!printFull) {
|
|
180
|
-
contentNew = util.inspect(content);
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
contentNew = String(content);
|
|
184
|
-
}
|
|
185
|
-
contentNew = formatter(contentNew, level);
|
|
186
|
-
fs.appendFile(filePath, contentNew + '\n', (err) => {
|
|
187
|
-
if (!!err) {
|
|
188
|
-
console.error(err);
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
function setupPrintToConsole(level, formatter) {
|
|
194
|
-
return (content, printFull) => {
|
|
195
|
-
let contentNew;
|
|
196
|
-
if (!!printFull) {
|
|
197
|
-
contentNew = util.inspect(content);
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
contentNew = String(content);
|
|
201
|
-
}
|
|
202
|
-
const colorFn = colors[level.COLOR];
|
|
203
|
-
contentNew = formatter(contentNew, level);
|
|
204
|
-
console.log(colorFn(contentNew));
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
function addDatetimeToFileName(filePath) {
|
|
208
|
-
const dateStr = new Date()
|
|
209
|
-
.toISOString()
|
|
210
|
-
.split('-')
|
|
211
|
-
.join('')
|
|
212
|
-
.split(':')
|
|
213
|
-
.join('')
|
|
214
|
-
.slice(0, 15);
|
|
215
|
-
const filePathArr = filePath.split('/'), lastIdx = filePathArr.length - 1, fileName = filePathArr[lastIdx], fileNameNew = dateStr + '_' + fileName;
|
|
216
|
-
filePathArr[lastIdx] = fileNameNew;
|
|
217
|
-
return filePathArr.join('/');
|
|
218
|
-
}
|
|
219
|
-
export default jetLogger();
|
package/dist/esm/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { JetLogger, jetLogger, default, } from './jetLogger.js';
|
package/dist/esm/jetLogger.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import colors from 'colors';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import util from 'util';
|
|
4
|
-
const Modes = {
|
|
5
|
-
CONSOLE: 'console',
|
|
6
|
-
FILE: 'file',
|
|
7
|
-
CUSTOM: 'custom',
|
|
8
|
-
OFF: 'off',
|
|
9
|
-
};
|
|
10
|
-
const Formats = {
|
|
11
|
-
LINE: 'line',
|
|
12
|
-
JSON: 'json',
|
|
13
|
-
};
|
|
14
|
-
const Levels = {
|
|
15
|
-
Info: {
|
|
16
|
-
COLOR: 'green',
|
|
17
|
-
PREFIX: 'INFO',
|
|
18
|
-
},
|
|
19
|
-
Important: {
|
|
20
|
-
COLOR: 'magenta',
|
|
21
|
-
PREFIX: 'IMPORTANT',
|
|
22
|
-
},
|
|
23
|
-
Warning: {
|
|
24
|
-
COLOR: 'yellow',
|
|
25
|
-
PREFIX: 'WARNING',
|
|
26
|
-
},
|
|
27
|
-
Error: {
|
|
28
|
-
COLOR: 'red',
|
|
29
|
-
PREFIX: 'ERROR',
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
const Defaults = {
|
|
33
|
-
MODE: Modes.CONSOLE,
|
|
34
|
-
FILE_PATH: 'jet-logger.log',
|
|
35
|
-
TIMESTAMP: true,
|
|
36
|
-
FORMAT: Formats.LINE,
|
|
37
|
-
CUSTOM_LOGGER_FUNCTION: () => ({}),
|
|
38
|
-
};
|
|
39
|
-
const Errors = {
|
|
40
|
-
CUSTOM_LOGGER: 'Custom logger mode set to true, but no custom logger was provided.',
|
|
41
|
-
MODE: 'The correct logger mode was not specified: Must be "custom", "file", ' +
|
|
42
|
-
'"off", or "console".',
|
|
43
|
-
};
|
|
44
|
-
export const JetLogger = {
|
|
45
|
-
Modes,
|
|
46
|
-
Formats,
|
|
47
|
-
};
|
|
48
|
-
export function jetLogger(options) {
|
|
49
|
-
let mode = Defaults.MODE, filePath = Defaults.FILE_PATH, timestamp = Defaults.TIMESTAMP, format = Defaults.FORMAT, customLogFn = Defaults.CUSTOM_LOGGER_FUNCTION;
|
|
50
|
-
if (options?.mode !== undefined) {
|
|
51
|
-
mode = options.mode;
|
|
52
|
-
}
|
|
53
|
-
else if (!!process.env.JET_LOGGER_MODE) {
|
|
54
|
-
mode = process.env.JET_LOGGER_MODE.toLowerCase();
|
|
55
|
-
}
|
|
56
|
-
if (mode === Modes.OFF) {
|
|
57
|
-
return {
|
|
58
|
-
info: (_, __) => ({}),
|
|
59
|
-
imp: (_, __) => ({}),
|
|
60
|
-
warn: (_, __) => ({}),
|
|
61
|
-
err: (_, __) => ({}),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
if (mode === Modes.CUSTOM) {
|
|
65
|
-
if (options?.customLogger !== undefined) {
|
|
66
|
-
customLogFn = options.customLogger;
|
|
67
|
-
}
|
|
68
|
-
if (!customLogFn) {
|
|
69
|
-
throw Error(Errors.CUSTOM_LOGGER);
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
info: setupPrintWithCustomLogger(Levels.Info, customLogFn),
|
|
73
|
-
imp: setupPrintWithCustomLogger(Levels.Important, customLogFn),
|
|
74
|
-
warn: setupPrintWithCustomLogger(Levels.Warning, customLogFn),
|
|
75
|
-
err: setupPrintWithCustomLogger(Levels.Error, customLogFn),
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
if (options?.filepath !== undefined) {
|
|
79
|
-
filePath = options.filepath;
|
|
80
|
-
}
|
|
81
|
-
else if (!!process.env.JET_LOGGER_FILEPATH) {
|
|
82
|
-
filePath = process.env.JET_LOGGER_FILEPATH;
|
|
83
|
-
}
|
|
84
|
-
if (options?.timestamp !== undefined) {
|
|
85
|
-
timestamp = options.timestamp;
|
|
86
|
-
}
|
|
87
|
-
else if (!!process.env.JET_LOGGER_TIMESTAMP) {
|
|
88
|
-
const envVar = process.env.JET_LOGGER_TIMESTAMP;
|
|
89
|
-
timestamp = envVar.toLowerCase() === 'true';
|
|
90
|
-
}
|
|
91
|
-
if (options?.format !== undefined) {
|
|
92
|
-
format = options.format;
|
|
93
|
-
}
|
|
94
|
-
else if (!!process.env.JET_LOGGER_FORMAT) {
|
|
95
|
-
format = process.env.JET_LOGGER_FORMAT.toLowerCase();
|
|
96
|
-
}
|
|
97
|
-
let formatter = () => '';
|
|
98
|
-
if (format === Formats.LINE) {
|
|
99
|
-
formatter = setupLineFormatter(timestamp);
|
|
100
|
-
}
|
|
101
|
-
else if (format === Formats.JSON) {
|
|
102
|
-
formatter = setupJsonFormatter(timestamp);
|
|
103
|
-
}
|
|
104
|
-
if (mode === Modes.FILE) {
|
|
105
|
-
let filePathDatetime = true;
|
|
106
|
-
if (options?.filepathDatetimeParam !== undefined) {
|
|
107
|
-
filePathDatetime = options.filepathDatetimeParam;
|
|
108
|
-
}
|
|
109
|
-
else if (!!process.env.JET_LOGGER_FILEPATH_DATETIME) {
|
|
110
|
-
const envVar = process.env.JET_LOGGER_FILEPATH_DATETIME;
|
|
111
|
-
filePathDatetime = envVar.toLowerCase() === 'true';
|
|
112
|
-
}
|
|
113
|
-
if (filePathDatetime) {
|
|
114
|
-
filePath = addDatetimeToFileName(filePath);
|
|
115
|
-
}
|
|
116
|
-
return {
|
|
117
|
-
info: setupPrintToFile(Levels.Info, formatter, filePath),
|
|
118
|
-
imp: setupPrintToFile(Levels.Important, formatter, filePath),
|
|
119
|
-
warn: setupPrintToFile(Levels.Warning, formatter, filePath),
|
|
120
|
-
err: setupPrintToFile(Levels.Error, formatter, filePath),
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
return {
|
|
124
|
-
info: setupPrintToConsole(Levels.Info, formatter),
|
|
125
|
-
imp: setupPrintToConsole(Levels.Important, formatter),
|
|
126
|
-
warn: setupPrintToConsole(Levels.Warning, formatter),
|
|
127
|
-
err: setupPrintToConsole(Levels.Error, formatter),
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
function setupPrintWithCustomLogger(level, customLogFn) {
|
|
131
|
-
return (content, printFull) => {
|
|
132
|
-
let contentNew;
|
|
133
|
-
if (printFull) {
|
|
134
|
-
contentNew = util.inspect(content);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
contentNew = String(content);
|
|
138
|
-
}
|
|
139
|
-
return customLogFn(new Date(), level.PREFIX, contentNew);
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
function setupLineFormatter(timestamp) {
|
|
143
|
-
if (timestamp) {
|
|
144
|
-
return (content, level) => {
|
|
145
|
-
const contentNew = level.PREFIX + ': ' + content, time = '[' + new Date().toISOString() + '] ';
|
|
146
|
-
return time + contentNew;
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
return (content, level) => {
|
|
151
|
-
return level.PREFIX + ': ' + content;
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
function setupJsonFormatter(timestamp) {
|
|
156
|
-
if (timestamp) {
|
|
157
|
-
return (content, level) => {
|
|
158
|
-
const json = {
|
|
159
|
-
level: level.PREFIX,
|
|
160
|
-
message: content,
|
|
161
|
-
};
|
|
162
|
-
json.timestamp = new Date().toISOString();
|
|
163
|
-
return JSON.stringify(json);
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
return (content, level) => {
|
|
168
|
-
const json = {
|
|
169
|
-
level: level.PREFIX,
|
|
170
|
-
message: content,
|
|
171
|
-
};
|
|
172
|
-
return JSON.stringify(json);
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
function setupPrintToFile(level, formatter, filePath) {
|
|
177
|
-
return (content, printFull) => {
|
|
178
|
-
let contentNew;
|
|
179
|
-
if (!!printFull) {
|
|
180
|
-
contentNew = util.inspect(content);
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
contentNew = String(content);
|
|
184
|
-
}
|
|
185
|
-
contentNew = formatter(contentNew, level);
|
|
186
|
-
fs.appendFile(filePath, contentNew + '\n', (err) => {
|
|
187
|
-
if (!!err) {
|
|
188
|
-
console.error(err);
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
function setupPrintToConsole(level, formatter) {
|
|
194
|
-
return (content, printFull) => {
|
|
195
|
-
let contentNew;
|
|
196
|
-
if (!!printFull) {
|
|
197
|
-
contentNew = util.inspect(content);
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
contentNew = String(content);
|
|
201
|
-
}
|
|
202
|
-
const colorFn = colors[level.COLOR];
|
|
203
|
-
contentNew = formatter(contentNew, level);
|
|
204
|
-
console.log(colorFn(contentNew));
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
function addDatetimeToFileName(filePath) {
|
|
208
|
-
const dateStr = new Date()
|
|
209
|
-
.toISOString()
|
|
210
|
-
.split('-')
|
|
211
|
-
.join('')
|
|
212
|
-
.split(':')
|
|
213
|
-
.join('')
|
|
214
|
-
.slice(0, 15);
|
|
215
|
-
const filePathArr = filePath.split('/'), lastIdx = filePathArr.length - 1, fileName = filePathArr[lastIdx], fileNameNew = dateStr + '_' + fileName;
|
|
216
|
-
filePathArr[lastIdx] = fileNameNew;
|
|
217
|
-
return filePathArr.join('/');
|
|
218
|
-
}
|
|
219
|
-
export default jetLogger();
|
package/dist/types/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { type CustomLogger, JetLogger, jetLogger, default, } from './jetLogger.js';
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
/******************************************************************************
|
|
2
|
-
Constants
|
|
3
|
-
******************************************************************************/
|
|
4
|
-
declare const Modes: {
|
|
5
|
-
readonly CONSOLE: "console";
|
|
6
|
-
readonly FILE: "file";
|
|
7
|
-
readonly CUSTOM: "custom";
|
|
8
|
-
readonly OFF: "off";
|
|
9
|
-
};
|
|
10
|
-
declare const Formats: {
|
|
11
|
-
readonly LINE: "line";
|
|
12
|
-
readonly JSON: "json";
|
|
13
|
-
};
|
|
14
|
-
export declare const JetLogger: {
|
|
15
|
-
readonly Modes: {
|
|
16
|
-
readonly CONSOLE: "console";
|
|
17
|
-
readonly FILE: "file";
|
|
18
|
-
readonly CUSTOM: "custom";
|
|
19
|
-
readonly OFF: "off";
|
|
20
|
-
};
|
|
21
|
-
readonly Formats: {
|
|
22
|
-
readonly LINE: "line";
|
|
23
|
-
readonly JSON: "json";
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
/******************************************************************************
|
|
27
|
-
Types
|
|
28
|
-
******************************************************************************/
|
|
29
|
-
type Modes = (typeof Modes)[keyof typeof Modes];
|
|
30
|
-
type Formats = (typeof Formats)[keyof typeof Formats];
|
|
31
|
-
type LogFunction = (content: unknown, printFull?: boolean) => void;
|
|
32
|
-
export type CustomLogger = (timestamp: Date, prefix: string, content: unknown) => void;
|
|
33
|
-
interface Options {
|
|
34
|
-
mode?: Modes;
|
|
35
|
-
filepath?: string;
|
|
36
|
-
filepathDatetimeParam?: boolean;
|
|
37
|
-
timestamp?: boolean;
|
|
38
|
-
format?: Formats;
|
|
39
|
-
customLogger?: CustomLogger;
|
|
40
|
-
}
|
|
41
|
-
/******************************************************************************
|
|
42
|
-
Functions
|
|
43
|
-
******************************************************************************/
|
|
44
|
-
/**
|
|
45
|
-
* Default function
|
|
46
|
-
*/
|
|
47
|
-
export declare function jetLogger(options?: Options): {
|
|
48
|
-
readonly info: LogFunction;
|
|
49
|
-
readonly imp: LogFunction;
|
|
50
|
-
readonly warn: LogFunction;
|
|
51
|
-
readonly err: LogFunction;
|
|
52
|
-
};
|
|
53
|
-
/******************************************************************************
|
|
54
|
-
Export
|
|
55
|
-
******************************************************************************/
|
|
56
|
-
declare const _default: {
|
|
57
|
-
readonly info: LogFunction;
|
|
58
|
-
readonly imp: LogFunction;
|
|
59
|
-
readonly warn: LogFunction;
|
|
60
|
-
readonly err: LogFunction;
|
|
61
|
-
};
|
|
62
|
-
export default _default;
|