jet-logger 3.0.0 → 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/README.md +154 -1
- package/lib/index.d.ts +16 -11
- package/lib/index.js +8 -8
- package/package.json +1 -5
package/README.md
CHANGED
|
@@ -35,7 +35,160 @@ npm install jet-logger
|
|
|
35
35
|
|
|
36
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
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`.
|
|
38
155
|
|
|
39
156
|
<p align="center">· · ·</p>
|
|
40
157
|
|
|
41
|
-
|
|
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
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
// Generated by dts-bundle-generator v9.5.1
|
|
2
2
|
|
|
3
|
+
type BaseTypes = Record<string, number> | Record<string, string>;
|
|
3
4
|
type Enum<O extends BaseTypes> = {
|
|
4
5
|
[K in keyof O]: O[K] extends string | number ? O[K] : never;
|
|
5
6
|
}[keyof O];
|
|
6
|
-
|
|
7
|
-
|
|
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: {
|
|
8
13
|
readonly CONSOLE: "console";
|
|
9
14
|
readonly FILE: "file";
|
|
10
15
|
readonly BROWSER: "browser";
|
|
11
16
|
readonly CUSTOM: "custom";
|
|
12
17
|
readonly OFF: "off";
|
|
13
18
|
};
|
|
19
|
+
type ModesTable = typeof ModesTable;
|
|
14
20
|
declare const Modes: {
|
|
15
21
|
readonly is: (val: unknown) => val is "console" | "file" | "browser" | "custom" | "off";
|
|
16
|
-
readonly
|
|
22
|
+
readonly table: () => {
|
|
17
23
|
readonly CONSOLE: "console";
|
|
18
24
|
readonly FILE: "file";
|
|
19
25
|
readonly BROWSER: "browser";
|
|
@@ -26,23 +32,22 @@ declare const Modes: {
|
|
|
26
32
|
readonly CUSTOM: "custom";
|
|
27
33
|
readonly OFF: "off";
|
|
28
34
|
};
|
|
29
|
-
type
|
|
30
|
-
|
|
31
|
-
declare const EFormats: {
|
|
35
|
+
type Modes = Enum<ModesTable>;
|
|
36
|
+
declare const FormatsTable: {
|
|
32
37
|
readonly LINE: "line";
|
|
33
38
|
readonly JSON: "json";
|
|
34
39
|
};
|
|
40
|
+
type FormatsTable = typeof FormatsTable;
|
|
35
41
|
declare const Formats: {
|
|
36
42
|
readonly is: (val: unknown) => val is "line" | "json";
|
|
37
|
-
readonly
|
|
43
|
+
readonly table: () => {
|
|
38
44
|
readonly LINE: "line";
|
|
39
45
|
readonly JSON: "json";
|
|
40
46
|
};
|
|
41
47
|
readonly LINE: "line";
|
|
42
48
|
readonly JSON: "json";
|
|
43
49
|
};
|
|
44
|
-
type
|
|
45
|
-
type Formats = Enum<EFormats$1>;
|
|
50
|
+
type Formats = Enum<FormatsTable>;
|
|
46
51
|
type Labels = "INFO" | "WARNING" | "ERROR" | "IMPORTANT";
|
|
47
52
|
type IOptions = {
|
|
48
53
|
format: Formats;
|
|
@@ -91,8 +96,8 @@ declare class InvalidOptionErr extends Error {
|
|
|
91
96
|
}
|
|
92
97
|
interface JetLogger {
|
|
93
98
|
(options?: JetLoggerOptions): JetLoggerInstance;
|
|
94
|
-
readonly Modes:
|
|
95
|
-
readonly Formats:
|
|
99
|
+
readonly Modes: EnumTable<typeof Modes>;
|
|
100
|
+
readonly Formats: EnumTable<typeof Formats>;
|
|
96
101
|
}
|
|
97
102
|
declare const DefaultLogger: JetLoggerInstance;
|
|
98
103
|
declare const JetLogger$1: JetLogger;
|
package/lib/index.js
CHANGED
|
@@ -1,12 +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
|
|
2
|
-
`),o=e.findIndex(
|
|
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
3
|
`).some(r=>K.test(r))?o:`${e}
|
|
4
|
-
${o}`:e}function
|
|
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(
|
|
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
6
|
`)}else{let o=this.#t(e,this.#o);process.stderr.write(o+`
|
|
7
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}=
|
|
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,
|
|
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
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}=
|
|
12
|
-
`]),out:(...
|
|
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jet-logger",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "A super quick, easy to setup TypeScript first logging tool for NodeJS and browsers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -29,11 +29,7 @@
|
|
|
29
29
|
"format": "prettier --write .",
|
|
30
30
|
"format:check": "prettier --check .",
|
|
31
31
|
"npm-data": "npm run build && npm pack --dry-run --json",
|
|
32
|
-
"prepack": "npm run readme:swap",
|
|
33
32
|
"prepublishOnly": "npm run build && tsc && npm run lint && npm run format:check && npm test && npm run test:browser && npm run verify:package",
|
|
34
|
-
"postpack": "npm run readme:restore",
|
|
35
|
-
"readme:swap": "tsx scripts/readme.ts swap",
|
|
36
|
-
"readme:restore": "tsx scripts/readme.ts restore",
|
|
37
33
|
"test": "vitest run",
|
|
38
34
|
"test:browser": "vitest run --config vitest.browser.config.ts",
|
|
39
35
|
"typecheck": "tsc",
|