@tryghost/pretty-stream 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +9 -14
  2. package/lib/PrettyStream.js +104 -80
  3. package/package.json +15 -15
package/README.md CHANGED
@@ -6,8 +6,7 @@
6
6
 
7
7
  or
8
8
 
9
- `yarn add @tryghost/pretty-stream`
10
-
9
+ `pnpm add @tryghost/pretty-stream`
11
10
 
12
11
  ## Purpose
13
12
 
@@ -19,26 +18,22 @@ Used by `@tryghost/logging` and `@tryghost/metrics`.
19
18
 
20
19
  ## Develop
21
20
 
22
- This is a mono repository, managed with [lerna](https://lernajs.io/).
21
+ This is a mono repository, managed with [Nx](https://nx.dev).
23
22
 
24
23
  Follow the instructions for the top-level repo.
25
- 1. `git clone` this repo & `cd` into it as usual
26
- 2. Run `yarn` to install top-level dependencies.
27
24
 
25
+ 1. `git clone` this repo & `cd` into it as usual
26
+ 2. Run `pnpm install` to install top-level dependencies.
28
27
 
29
28
  ## Run
30
29
 
31
- - `yarn dev`
32
-
30
+ - `pnpm dev`
33
31
 
34
32
  ## Test
35
33
 
36
- - `yarn lint` run just eslint
37
- - `yarn test` run lint and tests
38
-
39
-
40
-
34
+ - `pnpm lint` runs oxlint
35
+ - `pnpm test` runs lint and tests
41
36
 
42
- # Copyright & License
37
+ # Copyright & License
43
38
 
44
- Copyright (c) 2013-2026 Ghost Foundation - Released under the [MIT license](LICENSE).
39
+ Copyright (c) 2013-2026 Ghost Foundation - Released under the [MIT license](LICENSE).
@@ -17,7 +17,7 @@ const _private = {
17
17
  30: 'info',
18
18
  40: 'warn',
19
19
  50: 'error',
20
- 60: 'fatal'
20
+ 60: 'fatal',
21
21
  },
22
22
  colorForLevel: {
23
23
  10: 'grey',
@@ -25,7 +25,7 @@ const _private = {
25
25
  30: 'cyan',
26
26
  40: 'magenta',
27
27
  50: 'red',
28
- 60: 'inverse'
28
+ 60: 'inverse',
29
29
  },
30
30
  colors: {
31
31
  default: [39, 39],
@@ -41,26 +41,37 @@ const _private = {
41
41
  green: [32, 39],
42
42
  magenta: [35, 39],
43
43
  red: [31, 39],
44
- yellow: [33, 39]
45
- }
44
+ yellow: [33, 39],
45
+ },
46
46
  };
47
47
 
48
48
  function colorize(colors, value) {
49
49
  if (isArray(colors)) {
50
50
  return colors.reduce((acc, color) => colorize(color, acc), value);
51
51
  } else {
52
- return '\x1B[' + _private.colors[colors][0] + 'm' + value + '\x1B[' + _private.colors[colors][1] + 'm';
52
+ return (
53
+ '\x1B[' +
54
+ _private.colors[colors][0] +
55
+ 'm' +
56
+ value +
57
+ '\x1B[' +
58
+ _private.colors[colors][1] +
59
+ 'm'
60
+ );
53
61
  }
54
62
  }
55
63
 
56
64
  function statusCode(status) {
57
- /* eslint-disable indent */
58
- const color = status >= 500 ? 'red'
59
- : status >= 400 ? 'yellow'
60
- : status >= 300 ? 'cyan'
61
- : status >= 200 ? 'green'
62
- : 'default'; // no color
63
- /* eslint-enable indent */
65
+ const color =
66
+ status >= 500
67
+ ? 'red'
68
+ : status >= 400
69
+ ? 'yellow'
70
+ : status >= 300
71
+ ? 'cyan'
72
+ : status >= 200
73
+ ? 'green'
74
+ : 'default'; // no color
64
75
 
65
76
  return colorize(color, status);
66
77
  }
@@ -106,7 +117,10 @@ class PrettyStream extends Transform {
106
117
 
107
118
  if (data.time) {
108
119
  // If time is provided as a string in the expected format, use it directly
109
- if (typeof data.time === 'string' && /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(data.time)) {
120
+ if (
121
+ typeof data.time === 'string' &&
122
+ /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(data.time)
123
+ ) {
110
124
  time = data.time;
111
125
  } else {
112
126
  // Otherwise, parse and format it
@@ -126,99 +140,109 @@ class PrettyStream extends Transform {
126
140
  logLevel = '\x1B[' + codes[0] + 'm' + logLevel + '\x1B[' + codes[1] + 'm';
127
141
 
128
142
  if (data.req) {
129
- output += format('[%s] %s "%s %s" %s %s\n',
143
+ output += format(
144
+ '[%s] %s "%s %s" %s %s\n',
130
145
  time,
131
146
  logLevel,
132
147
  data.req.method.toUpperCase(),
133
148
  get(data, 'req.originalUrl'),
134
149
  statusCode(get(data, 'res.statusCode')),
135
- get(data, 'res.responseTime')
150
+ get(data, 'res.responseTime'),
136
151
  );
137
152
  } else if (data.msg === undefined) {
138
- output += format('[%s] %s\n',
139
- time,
140
- logLevel
141
- );
153
+ output += format('[%s] %s\n', time, logLevel);
142
154
  } else {
143
155
  bodyPretty += data.msg;
144
156
  output += format('[%s] %s %s\n', time, logLevel, bodyPretty);
145
157
  }
146
158
 
147
- each(Object.fromEntries(Object.entries(data).filter(([key]) => !OMITTED_KEYS.includes(key))), function (value, key) {
148
- // we always output errors for now
149
- if (isObject(value) && value.message && value.stack) {
150
- let error = '\n';
151
-
152
- if (value.errorType) {
153
- error += colorize(_private.colorForLevel[data.level], 'Type: ' + value.errorType) + '\n';
154
- }
155
-
156
- error += colorize(_private.colorForLevel[data.level], value.message) + '\n\n';
157
-
158
- if (value.context) {
159
- error += colorize('white', value.context) + '\n';
160
- }
161
-
162
- if (value.help) {
163
- error += colorize('yellow', value.help) + '\n';
164
- }
159
+ each(
160
+ Object.fromEntries(Object.entries(data).filter(([key]) => !OMITTED_KEYS.includes(key))),
161
+ function (value, key) {
162
+ // we always output errors for now
163
+ if (isObject(value) && value.message && value.stack) {
164
+ let error = '\n';
165
+
166
+ if (value.errorType) {
167
+ error +=
168
+ colorize(
169
+ _private.colorForLevel[data.level],
170
+ 'Type: ' + value.errorType,
171
+ ) + '\n';
172
+ }
165
173
 
166
- if (value.context || value.help) {
167
- error += '\n';
168
- }
174
+ error += colorize(_private.colorForLevel[data.level], value.message) + '\n\n';
169
175
 
170
- if (value.id) {
171
- error += colorize(['white', 'bold'], 'Error ID:') + '\n';
172
- error += ' ' + colorize('grey', value.id) + '\n\n';
173
- }
176
+ if (value.context) {
177
+ error += colorize('white', value.context) + '\n';
178
+ }
174
179
 
175
- if (value.code) {
176
- error += colorize(['white', 'bold'], 'Error Code: ') + '\n';
177
- error += ' ' + colorize('grey', value.code) + '\n\n';
178
- }
180
+ if (value.help) {
181
+ error += colorize('yellow', value.help) + '\n';
182
+ }
179
183
 
180
- if (value.errorDetails) {
181
- let details = value.errorDetails;
184
+ if (value.context || value.help) {
185
+ error += '\n';
186
+ }
182
187
 
183
- try {
184
- const jsonDetails = JSON.parse(value.errorDetails);
185
- details = isArray(jsonDetails) ? jsonDetails[0] : jsonDetails;
186
- } catch (err) {
187
- // no need for special handling as we default to unparsed 'errorDetails'
188
+ if (value.id) {
189
+ error += colorize(['white', 'bold'], 'Error ID:') + '\n';
190
+ error += ' ' + colorize('grey', value.id) + '\n\n';
188
191
  }
189
192
 
190
- const pretty = prettyjson.render(details, {
191
- noColor: true
192
- }, 4);
193
+ if (value.code) {
194
+ error += colorize(['white', 'bold'], 'Error Code: ') + '\n';
195
+ error += ' ' + colorize('grey', value.code) + '\n\n';
196
+ }
193
197
 
194
- error += colorize(['white', 'bold'], 'Details:') + '\n';
195
- error += colorize('grey', pretty) + '\n\n';
196
- }
198
+ if (value.errorDetails) {
199
+ let details = value.errorDetails;
200
+
201
+ try {
202
+ const jsonDetails = JSON.parse(value.errorDetails);
203
+ details = isArray(jsonDetails) ? jsonDetails[0] : jsonDetails;
204
+ } catch {
205
+ // no need for special handling as we default to unparsed 'errorDetails'
206
+ }
207
+
208
+ const pretty = prettyjson.render(
209
+ details,
210
+ {
211
+ noColor: true,
212
+ },
213
+ 4,
214
+ );
215
+
216
+ error += colorize(['white', 'bold'], 'Details:') + '\n';
217
+ error += colorize('grey', pretty) + '\n\n';
218
+ }
197
219
 
198
- if (value.stack && !value.hideStack) {
199
- error += colorize('grey', '----------------------------------------') + '\n\n';
200
- error += colorize('grey', value.stack) + '\n';
201
- }
220
+ if (value.stack && !value.hideStack) {
221
+ error +=
222
+ colorize('grey', '----------------------------------------') + '\n\n';
223
+ error += colorize('grey', value.stack) + '\n';
224
+ }
202
225
 
203
- output += format('%s\n', colorize(_private.colorForLevel[data.level], error));
204
- } else if (isObject(value)) {
205
- bodyPretty += '\n' + colorize('yellow', key.toUpperCase()) + '\n';
226
+ output += format('%s\n', colorize(_private.colorForLevel[data.level], error));
227
+ } else if (isObject(value)) {
228
+ bodyPretty += '\n' + colorize('yellow', key.toUpperCase()) + '\n';
206
229
 
207
- let sanitized = {};
230
+ let sanitized = {};
208
231
 
209
- each(value, function (innerValue, innerKey) {
210
- if (!isEmpty(innerValue)) {
211
- sanitized[innerKey] = innerValue;
212
- }
213
- });
232
+ each(value, function (innerValue, innerKey) {
233
+ if (!isEmpty(innerValue)) {
234
+ sanitized[innerKey] = innerValue;
235
+ }
236
+ });
214
237
 
215
- bodyPretty += prettyjson.render(sanitized, {}) + '\n';
216
- } else {
217
- bodyPretty += prettyjson.render(value, {}) + '\n';
218
- }
219
- });
238
+ bodyPretty += prettyjson.render(sanitized, {}) + '\n';
239
+ } else {
240
+ bodyPretty += prettyjson.render(value, {}) + '\n';
241
+ }
242
+ },
243
+ );
220
244
 
221
- if (this.mode !== 'short' && (bodyPretty !== data.msg)) {
245
+ if (this.mode !== 'short' && bodyPretty !== data.msg) {
222
246
  output += format('%s\n', colorize('grey', bodyPretty));
223
247
  }
224
248
 
package/package.json CHANGED
@@ -1,33 +1,33 @@
1
1
  {
2
2
  "name": "@tryghost/pretty-stream",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
+ "license": "MIT",
5
+ "author": "Ghost Foundation",
4
6
  "repository": {
5
7
  "type": "git",
6
8
  "url": "git+https://github.com/TryGhost/framework.git",
7
9
  "directory": "packages/pretty-stream"
8
10
  },
9
- "author": "Ghost Foundation",
10
- "license": "MIT",
11
- "main": "index.js",
12
- "scripts": {
13
- "dev": "echo \"Implement me!\"",
14
- "test": "NODE_ENV=testing vitest run --coverage --config ../../vitest.config.ts",
15
- "lint": "eslint . --ext .js --cache",
16
- "posttest": "yarn lint"
17
- },
18
11
  "files": [
19
12
  "index.js",
20
13
  "lib"
21
14
  ],
15
+ "main": "index.js",
22
16
  "publishConfig": {
23
17
  "access": "public"
24
18
  },
25
- "devDependencies": {
26
- "sinon": "21.0.2"
27
- },
28
19
  "dependencies": {
29
20
  "date-format": "4.0.14",
30
- "lodash": "4.17.23",
21
+ "lodash": "4.18.1",
31
22
  "prettyjson": "1.2.5"
23
+ },
24
+ "devDependencies": {
25
+ "sinon": "21.1.2"
26
+ },
27
+ "scripts": {
28
+ "dev": "echo \"Implement me!\"",
29
+ "test": "NODE_ENV=testing vitest run --coverage --config ../../vitest.config.ts",
30
+ "lint": "oxlint -c ../../.oxlintrc.json .",
31
+ "posttest": "pnpm run lint"
32
32
  }
33
- }
33
+ }