@percy/sdk-utils 1.10.1 → 1.10.3

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 CHANGED
@@ -43,8 +43,7 @@ percy.domScript === fs.readFile(require.resolve('@percy/dom'))
43
43
  Returns `true` or `false` if the Percy CLI API server is running. Calls the server's `/healthcheck`
44
44
  endpoint and populates information for the [`percy`](#percy) property. The result of this function
45
45
  is cached and subsequent calls will return the first cached result. If the healthcheck fails, will
46
- log a message unless the CLI loglevel is `quiet` or `silent`. Upon a successful health check, a
47
- remote logging connection is also established.
46
+ log a message unless the CLI loglevel is `quiet` or `silent`.
48
47
 
49
48
  ``` js
50
49
  import { isPercyEnabled } from '@percy/sdk-utils'
package/dist/bundle.js CHANGED
@@ -6,6 +6,62 @@
6
6
  process.env = process.env || {};
7
7
  process.env.__PERCY_BROWSERIFIED__ = true;
8
8
 
9
+ // Used when determining if a message should be logged
10
+ const LOG_LEVELS = {
11
+ debug: 0,
12
+ info: 1,
13
+ warn: 2,
14
+ error: 3
15
+ }; // Create a small logger util using the specified namespace
16
+
17
+ function logger(namespace) {
18
+ return Object.keys(LOG_LEVELS).reduce((ns, lvl) => Object.assign(ns, {
19
+ [lvl]: function () {
20
+ for (var _len = arguments.length, a = new Array(_len), _key = 0; _key < _len; _key++) {
21
+ a[_key] = arguments[_key];
22
+ }
23
+
24
+ return logger.log(namespace, lvl, ...a);
25
+ }
26
+ }), {});
27
+ } // Set and/or return the local loglevel
28
+
29
+ const loglevel = logger.loglevel = lvl => {
30
+ return loglevel.lvl = lvl || loglevel.lvl || process.env.PERCY_LOGLEVEL || 'info';
31
+ }; // Track and send/write logs for the specified namespace and log level
32
+
33
+
34
+ const log = logger.log = (ns, lvl, msg, meta) => {
35
+ let err = typeof msg !== 'string' && (lvl === 'error' || lvl === 'debug'); // keep log history of full message
36
+
37
+ let message = err ? msg.stack : msg.toString();
38
+ let [debug, level, timestamp, error] = [ns, lvl, Date.now(), !!err];
39
+ (log.history || (log.history = [])).push({
40
+ debug,
41
+ level,
42
+ message,
43
+ meta,
44
+ timestamp,
45
+ error
46
+ }); // check if the specific level is within the local loglevel range
47
+
48
+ if (LOG_LEVELS[lvl] != null && LOG_LEVELS[lvl] >= LOG_LEVELS[loglevel()]) {
49
+ let debug = loglevel() === 'debug';
50
+ let label = debug ? `percy:${ns}` : 'percy'; // colorize the label when possible for consistency with the CLI logger
51
+
52
+ if (!process.env.__PERCY_BROWSERIFIED__) label = `\u001b[95m${label}\u001b[39m`;
53
+ msg = `[${label}] ${err && debug && msg.stack || msg}`;
54
+
55
+ if (process.env.__PERCY_BROWSERIFIED__) {
56
+ // use console[warn|error|log] in browsers
57
+ console[['warn', 'error'].includes(lvl) ? lvl : 'log'](msg);
58
+ } else {
59
+ // use process[stdout|stderr].write in node
60
+ process[lvl === 'info' ? 'stdout' : 'stderr'].write(msg + '\n');
61
+ }
62
+ }
63
+ };
64
+
9
65
  // helper to create a version object from a string
10
66
  function toVersion(str) {
11
67
  str || (str = '0.0.0');
@@ -65,135 +121,6 @@
65
121
 
66
122
  };
67
123
 
68
- const LOG_LEVELS = {
69
- debug: 0,
70
- info: 1,
71
- warn: 2,
72
- error: 3
73
- }; // Create a small logger util using the specified namespace
74
-
75
- function logger(namespace) {
76
- return Object.keys(LOG_LEVELS).reduce((ns, lvl) => Object.assign(ns, {
77
- [lvl]: function () {
78
- for (var _len = arguments.length, a = new Array(_len), _key = 0; _key < _len; _key++) {
79
- a[_key] = arguments[_key];
80
- }
81
-
82
- return logger.log(namespace, lvl, ...a);
83
- }
84
- }), {});
85
- } // Set and/or return the local loglevel
86
-
87
- const loglevel = logger.loglevel = lvl => {
88
- return loglevel.lvl = lvl || loglevel.lvl || process.env.PERCY_LOGLEVEL || 'info';
89
- }; // Track and send/write logs for the specified namespace and log level
90
-
91
-
92
- const log = logger.log = (ns, lvl, msg, meta) => {
93
- let err = typeof msg !== 'string' && (lvl === 'error' || lvl === 'debug');
94
- meta = {
95
- remote: true,
96
- ...meta
97
- };
98
-
99
- if (remote.socket) {
100
- // prefer remote logging when available and serialize any errors
101
- if (err) msg = {
102
- name: msg.name,
103
- message: msg.message,
104
- stack: msg.stack
105
- };
106
- return remote.socket.send(JSON.stringify({
107
- log: [ns, lvl, msg, meta]
108
- }));
109
- } else {
110
- // keep log history of full message when not remote
111
- let message = err ? msg.stack : msg.toString();
112
- let [debug, level, timestamp, error] = [ns, lvl, Date.now(), !!err];
113
- (log.history || (log.history = [])).push({
114
- debug,
115
- level,
116
- message,
117
- meta,
118
- timestamp,
119
- error
120
- });
121
- } // check if the specific level is within the local loglevel range
122
-
123
-
124
- if (LOG_LEVELS[lvl] != null && LOG_LEVELS[lvl] >= LOG_LEVELS[loglevel()]) {
125
- let debug = loglevel() === 'debug';
126
- let label = debug ? `percy:${ns}` : 'percy'; // colorize the label when possible for consistency with the CLI logger
127
-
128
- if (!process.env.__PERCY_BROWSERIFIED__) label = `\u001b[95m${label}\u001b[39m`;
129
- msg = `[${label}] ${err && debug && msg.stack || msg}`;
130
-
131
- if (process.env.__PERCY_BROWSERIFIED__) {
132
- // use console[warn|error|log] in browsers
133
- console[['warn', 'error'].includes(lvl) ? lvl : 'log'](msg);
134
- } else {
135
- // use process[stdout|stderr].write in node
136
- process[lvl === 'info' ? 'stdout' : 'stderr'].write(msg + '\n');
137
- }
138
- }
139
- }; // Create a new WebSocket and resolve with it once connected
140
-
141
-
142
- async function createWebSocket(address) {
143
- let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
144
- // attempt to import `ws` in node environments
145
- let WebSocket = process.env.__PERCY_BROWSERIFIED__
146
- /* eslint-disable-next-line import/no-extraneous-dependencies */
147
- ? window.WebSocket : (await ({})).default;
148
- let ws = new WebSocket(address.replace(/^http/, 'ws'));
149
- return new Promise((resolve, reject) => {
150
- let done = ws.onopen = ws.onerror = e => {
151
- var _ws$_socket;
152
-
153
- (_ws$_socket = ws._socket) === null || _ws$_socket === void 0 ? void 0 : _ws$_socket.unref();
154
- clearTimeout(timeoutid);
155
- ws.onopen = ws.onerror = null;
156
- if (!e.error && e.type !== 'error') return resolve(ws);else reject(e.error || 'Error: Socket connection failed');
157
- };
158
-
159
- let timeoutid = setTimeout(done, timeout, {
160
- error: 'Error: Socket connection timed out'
161
- });
162
- });
163
- } // Connect to a remote logger at the specified address within the timeout
164
-
165
-
166
- const remote = logger.remote = async timeout => {
167
- try {
168
- var _remote$socket;
169
-
170
- // already connected
171
- if (((_remote$socket = remote.socket) === null || _remote$socket === void 0 ? void 0 : _remote$socket.readyState) === 1) return; // connect to namespaced logging address
172
-
173
- let address = new URL('/logger', info.address).href; // create and cache a websocket connection
174
-
175
- let ws = remote.socket = await createWebSocket(address, timeout);
176
- await new Promise((resolve, reject) => {
177
- // accept loglevel updates and resolve after first message
178
- ws.onmessage = e => resolve(loglevel(JSON.parse(e.data).loglevel));
179
-
180
- ws.onclose = () => {
181
- // cleanup listeners and reject if not resolved
182
- remote.socket = ws.onmessage = ws.onclose = null;
183
- reject(new Error('Connection closed'));
184
- };
185
- }); // send any messages already logged in this environment
186
-
187
- if (log.history) ws.send(JSON.stringify({
188
- messages: log.history
189
- }));
190
- } catch (err) {
191
- // there was an error connecting, will fallback to minimal logging
192
- logger.log('utils', 'debug', 'Unable to connect to remote logger');
193
- logger.log('utils', 'debug', err);
194
- }
195
- };
196
-
197
124
  async function request(path) {
198
125
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
199
126
  let response = await request.fetch(`${info.address}${path}`, options); // maybe parse response body as json
@@ -282,10 +209,6 @@
282
209
  log.info('Percy is not running, disabling snapshots');
283
210
  log.debug(error);
284
211
  }
285
-
286
- if (info.enabled) {
287
- await logger.remote();
288
- }
289
212
  }
290
213
 
291
214
  return info.enabled;
package/dist/logger.js CHANGED
@@ -5,15 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  exports.logger = logger;
8
-
9
- var _percyInfo = _interopRequireDefault(require("./percy-info.js"));
10
-
11
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12
-
13
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
14
-
15
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
16
-
17
8
  // Used when determining if a message should be logged
18
9
  const LOG_LEVELS = {
19
10
  debug: 0,
@@ -35,36 +26,18 @@ const loglevel = logger.loglevel = lvl => {
35
26
 
36
27
 
37
28
  const log = logger.log = (ns, lvl, msg, meta) => {
38
- let err = typeof msg !== 'string' && (lvl === 'error' || lvl === 'debug');
39
- meta = {
40
- remote: true,
41
- ...meta
42
- };
43
-
44
- if (remote.socket) {
45
- // prefer remote logging when available and serialize any errors
46
- if (err) msg = {
47
- name: msg.name,
48
- message: msg.message,
49
- stack: msg.stack
50
- };
51
- return remote.socket.send(JSON.stringify({
52
- log: [ns, lvl, msg, meta]
53
- }));
54
- } else {
55
- // keep log history of full message when not remote
56
- let message = err ? msg.stack : msg.toString();
57
- let [debug, level, timestamp, error] = [ns, lvl, Date.now(), !!err];
58
- (log.history || (log.history = [])).push({
59
- debug,
60
- level,
61
- message,
62
- meta,
63
- timestamp,
64
- error
65
- });
66
- } // check if the specific level is within the local loglevel range
67
-
29
+ let err = typeof msg !== 'string' && (lvl === 'error' || lvl === 'debug'); // keep log history of full message
30
+
31
+ let message = err ? msg.stack : msg.toString();
32
+ let [debug, level, timestamp, error] = [ns, lvl, Date.now(), !!err];
33
+ (log.history || (log.history = [])).push({
34
+ debug,
35
+ level,
36
+ message,
37
+ meta,
38
+ timestamp,
39
+ error
40
+ }); // check if the specific level is within the local loglevel range
68
41
 
69
42
  if (LOG_LEVELS[lvl] != null && LOG_LEVELS[lvl] >= LOG_LEVELS[loglevel()]) {
70
43
  let debug = loglevel() === 'debug';
@@ -81,61 +54,6 @@ const log = logger.log = (ns, lvl, msg, meta) => {
81
54
  process[lvl === 'info' ? 'stdout' : 'stderr'].write(msg + '\n');
82
55
  }
83
56
  }
84
- }; // Create a new WebSocket and resolve with it once connected
85
-
86
-
87
- async function createWebSocket(address, timeout = 1000) {
88
- // attempt to import `ws` in node environments
89
- let WebSocket = process.env.__PERCY_BROWSERIFIED__
90
- /* eslint-disable-next-line import/no-extraneous-dependencies */
91
- ? window.WebSocket : (await Promise.resolve().then(() => _interopRequireWildcard(require('ws')))).default;
92
- let ws = new WebSocket(address.replace(/^http/, 'ws'));
93
- return new Promise((resolve, reject) => {
94
- let done = ws.onopen = ws.onerror = e => {
95
- var _ws$_socket;
96
-
97
- (_ws$_socket = ws._socket) === null || _ws$_socket === void 0 ? void 0 : _ws$_socket.unref();
98
- clearTimeout(timeoutid);
99
- ws.onopen = ws.onerror = null;
100
- if (!e.error && e.type !== 'error') return resolve(ws);else reject(e.error || 'Error: Socket connection failed');
101
- };
102
-
103
- let timeoutid = setTimeout(done, timeout, {
104
- error: 'Error: Socket connection timed out'
105
- });
106
- });
107
- } // Connect to a remote logger at the specified address within the timeout
108
-
109
-
110
- const remote = logger.remote = async timeout => {
111
- try {
112
- var _remote$socket;
113
-
114
- // already connected
115
- if (((_remote$socket = remote.socket) === null || _remote$socket === void 0 ? void 0 : _remote$socket.readyState) === 1) return; // connect to namespaced logging address
116
-
117
- let address = new URL('/logger', _percyInfo.default.address).href; // create and cache a websocket connection
118
-
119
- let ws = remote.socket = await createWebSocket(address, timeout);
120
- await new Promise((resolve, reject) => {
121
- // accept loglevel updates and resolve after first message
122
- ws.onmessage = e => resolve(loglevel(JSON.parse(e.data).loglevel));
123
-
124
- ws.onclose = () => {
125
- // cleanup listeners and reject if not resolved
126
- remote.socket = ws.onmessage = ws.onclose = null;
127
- reject(new Error('Connection closed'));
128
- };
129
- }); // send any messages already logged in this environment
130
-
131
- if (log.history) ws.send(JSON.stringify({
132
- messages: log.history
133
- }));
134
- } catch (err) {
135
- // there was an error connecting, will fallback to minimal logging
136
- logger.log('utils', 'debug', 'Unable to connect to remote logger');
137
- logger.log('utils', 'debug', err);
138
- }
139
57
  };
140
58
 
141
59
  var _default = logger;
@@ -38,10 +38,6 @@ async function isPercyEnabled() {
38
38
  log.info('Percy is not running, disabling snapshots');
39
39
  log.debug(error);
40
40
  }
41
-
42
- if (_percyInfo.default.enabled) {
43
- await _logger.default.remote();
44
- }
45
41
  }
46
42
 
47
43
  return _percyInfo.default.enabled;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/sdk-utils",
3
- "version": "1.10.1",
3
+ "version": "1.10.3",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -50,5 +50,5 @@
50
50
  ]
51
51
  }
52
52
  },
53
- "gitHead": "3e16144300e8b49aab638ceb699630f4be71bb9f"
53
+ "gitHead": "a9858d20a9b9708da0464c0617b32b2ee1c97433"
54
54
  }
package/test/client.js CHANGED
@@ -25,7 +25,6 @@
25
25
  delete process.env.PERCY_LOGLEVEL;
26
26
  delete process.env.PERCY_SERVER_ADDRESS;
27
27
  await helpers.test('reset');
28
- await utils.logger.remote();
29
28
  },
30
29
 
31
30
  async test(cmd, arg) {
package/test/helpers.js CHANGED
@@ -11,7 +11,6 @@ const helpers = {
11
11
  delete process.env.PERCY_LOGLEVEL;
12
12
  delete process.env.PERCY_SERVER_ADDRESS;
13
13
  await helpers.test('reset');
14
- await utils.logger.remote();
15
14
  },
16
15
 
17
16
  async test(cmd, arg) {