update devDependencies, eslint config, address lint issues
[squeep-indieauth-helper] / lib / common.js
1 'use strict';
2
3 /**
4 * Pick out useful got response fields.
5 * @param {GotResponse} res
6 * @returns {Object}
7 */
8 const gotResponseLogData = (res) => {
9 const data = pick(res, [
10 'statusCode',
11 'statusMessage',
12 'headers',
13 'body',
14 'url',
15 'error',
16 ]);
17 if (typeof res.body === 'string') {
18 data.body = logTruncate(data.body, 100);
19 } else if (res.body instanceof Buffer) {
20 data.body = `<Buffer ${res.body.byteLength} bytes>`;
21 }
22 data.elapsedTimeMs = res?.timings?.phases?.total;
23 if (res?.redirectUrls?.length) {
24 data.redirectUrls = res.redirectUrls;
25 }
26 if (res?.retryCount) {
27 data.retryCount = res.retryCount;
28 }
29 return data;
30 };
31
32
33 /**
34 * Limit length of string to keep logs sane
35 * @param {String} str
36 * @param {Number} len
37 * @returns {String}
38 */
39 const logTruncate = (str, len) => {
40 if (typeof str !== 'string' || str.toString().length <= len) {
41 return str;
42 }
43 return str.toString().slice(0, len) + `... (${str.toString().length} bytes)`;
44 };
45
46
47 /**
48 * Return a new object with selected props.
49 * @param {Object} obj
50 * @param {String[]} props
51 */
52 const pick = (obj, props) => {
53 return props.reduce((acc, prop) => {
54 if (prop in obj) {
55 acc[prop] = obj[prop]; // eslint-disable-line security/detect-object-injection
56 }
57 return acc;
58 }, {});
59 };
60
61
62 /**
63 * Return a set containing non-shared items between two sets.
64 * @param {Set} a
65 * @param {Set} b
66 * @returns {Set}
67 */
68 const setSymmetricDifference = (a, b) => {
69 const d = new Set(a);
70 for (const x of b) {
71 if (d.has(x)) {
72 d.delete(x);
73 } else {
74 d.add(x);
75 }
76 }
77 return d;
78 };
79
80
81 /**
82 * URL objects have weird names.
83 * @param {String} component
84 * @returns {String}
85 */
86 const properURLComponentName = (component) => {
87 // eslint-disable-next-line security/detect-object-injection
88 return {
89 hash: 'fragment',
90 protocol: 'scheme',
91 }[component] || component;
92 };
93
94
95 module.exports = {
96 gotResponseLogData,
97 logTruncate,
98 pick,
99 setSymmetricDifference,
100 properURLComponentName,
101 };