@percy/sdk-utils 1.1.0 → 1.1.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/dist/bundle.js +129 -445
- package/dist/index.js +72 -10
- package/dist/logger.js +140 -0
- package/dist/percy-dom.js +22 -8
- package/dist/percy-enabled.js +33 -37
- package/dist/percy-idle.js +18 -4
- package/dist/percy-info.js +9 -1
- package/dist/post-snapshot.js +21 -7
- package/dist/request.js +21 -5
- package/package.json +3 -13
- package/test/client.js +99 -153
- package/test/helpers.js +90 -8
- package/test/server.js +13 -16
package/dist/logger.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
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
|
+
// Used when determining if a message should be logged
|
|
18
|
+
const LOG_LEVELS = {
|
|
19
|
+
debug: 0,
|
|
20
|
+
info: 1,
|
|
21
|
+
warn: 2,
|
|
22
|
+
error: 3
|
|
23
|
+
}; // Create a small logger util using the specified namespace
|
|
24
|
+
|
|
25
|
+
function logger(namespace) {
|
|
26
|
+
return Object.keys(LOG_LEVELS).reduce((ns, lvl) => Object.assign(ns, {
|
|
27
|
+
[lvl]: (...a) => logger.log(namespace, lvl, ...a)
|
|
28
|
+
}), {});
|
|
29
|
+
} // Set and/or return the local loglevel
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
const loglevel = logger.loglevel = lvl => {
|
|
33
|
+
return loglevel.lvl = lvl || loglevel.lvl || process.env.PERCY_LOGLEVEL || 'info';
|
|
34
|
+
}; // Track and send/write logs for the specified namespace and log level
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
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 when not remote
|
|
56
|
+
let [debug, level, message, timestamp] = [ns, lvl, msg, Date.now()];
|
|
57
|
+
(log.history || (log.history = [])).push({
|
|
58
|
+
debug,
|
|
59
|
+
level,
|
|
60
|
+
message,
|
|
61
|
+
meta,
|
|
62
|
+
timestamp
|
|
63
|
+
});
|
|
64
|
+
} // check if the specific level is within the local loglevel range
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if (LOG_LEVELS[lvl] != null && LOG_LEVELS[lvl] >= LOG_LEVELS[loglevel()]) {
|
|
68
|
+
var _msg;
|
|
69
|
+
|
|
70
|
+
let debug = loglevel() === 'debug';
|
|
71
|
+
let label = debug ? `percy:${ns}` : 'percy'; // colorize the label when possible for consistency with the CLI logger
|
|
72
|
+
|
|
73
|
+
if (!process.env.__PERCY_BROWSERIFIED__) label = `\u001b[95m${label}\u001b[39m`;
|
|
74
|
+
msg = `[${label}] ${err && debug && ((_msg = msg) === null || _msg === void 0 ? void 0 : _msg.stack) || msg}`;
|
|
75
|
+
|
|
76
|
+
if (process.env.__PERCY_BROWSERIFIED__) {
|
|
77
|
+
// use console[warn|error|log] in browsers
|
|
78
|
+
console[['warn', 'error'].includes(lvl) ? lvl : 'log'](msg);
|
|
79
|
+
} else {
|
|
80
|
+
// use process[stdout|stderr].write in node
|
|
81
|
+
process[lvl === 'info' ? 'stdout' : 'stderr'].write(msg + '\n');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
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); // accept loglevel updates
|
|
120
|
+
|
|
121
|
+
/* istanbul ignore next: difficult to test currently */
|
|
122
|
+
|
|
123
|
+
ws.onmessage = e => loglevel(JSON.parse(e.data).loglevel); // cleanup message handler on close
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
ws.onclose = () => remote.socket = ws.onmessage = ws.onclose = null; // send any messages already logged in this environment
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
if (log.history) ws.send(JSON.stringify({
|
|
130
|
+
messages: log.history
|
|
131
|
+
}));
|
|
132
|
+
} catch (err) {
|
|
133
|
+
// there was an error connecting, will fallback to minimal logging
|
|
134
|
+
logger.log('utils', 'debug', 'Unable to connect to remote logger');
|
|
135
|
+
logger.log('utils', 'debug', err);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
var _default = logger;
|
|
140
|
+
exports.default = _default;
|
package/dist/percy-dom.js
CHANGED
|
@@ -1,12 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
import request from './request.js'; // Fetch and cache the @percy/dom script
|
|
1
|
+
"use strict";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
exports.fetchPercyDOM = fetchPercyDOM;
|
|
8
|
+
|
|
9
|
+
var _percyInfo = _interopRequireDefault(require("./percy-info.js"));
|
|
10
|
+
|
|
11
|
+
var _request = _interopRequireDefault(require("./request.js"));
|
|
12
|
+
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
|
|
15
|
+
// Fetch and cache the @percy/dom script
|
|
16
|
+
async function fetchPercyDOM() {
|
|
17
|
+
if (_percyInfo.default.domScript == null) {
|
|
18
|
+
let response = await (0, _request.default)('/percy/dom.js');
|
|
19
|
+
_percyInfo.default.domScript = response.body;
|
|
8
20
|
}
|
|
9
21
|
|
|
10
|
-
return
|
|
22
|
+
return _percyInfo.default.domScript;
|
|
11
23
|
}
|
|
12
|
-
|
|
24
|
+
|
|
25
|
+
var _default = fetchPercyDOM;
|
|
26
|
+
exports.default = _default;
|
package/dist/percy-enabled.js
CHANGED
|
@@ -1,55 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return new window.WebSocket(url);
|
|
11
|
-
} else {
|
|
12
|
-
/* eslint-disable-next-line import/no-extraneous-dependencies */
|
|
13
|
-
let {
|
|
14
|
-
default: WebSocket
|
|
15
|
-
} = await import('ws');
|
|
16
|
-
let ws = new WebSocket(url); // allow node to exit with an active connection
|
|
17
|
-
|
|
18
|
-
return ws.once('open', () => ws._socket.unref());
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
} // Check if Percy is enabled using the healthcheck endpoint
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
exports.isPercyEnabled = isPercyEnabled;
|
|
8
|
+
|
|
9
|
+
var _percyInfo = _interopRequireDefault(require("./percy-info.js"));
|
|
22
10
|
|
|
11
|
+
var _request = _interopRequireDefault(require("./request.js"));
|
|
23
12
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
var _logger = _interopRequireDefault(require("./logger.js"));
|
|
14
|
+
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
+
|
|
17
|
+
// Check if Percy is enabled using the healthcheck endpoint
|
|
18
|
+
async function isPercyEnabled() {
|
|
19
|
+
if (_percyInfo.default.enabled == null) {
|
|
20
|
+
let log = (0, _logger.default)('utils');
|
|
27
21
|
let error;
|
|
28
22
|
|
|
29
23
|
try {
|
|
30
|
-
let response = await
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
let response = await (0, _request.default)('/percy/healthcheck');
|
|
25
|
+
_percyInfo.default.version = response.headers['x-percy-core-version'];
|
|
26
|
+
_percyInfo.default.config = response.body.config;
|
|
27
|
+
_percyInfo.default.enabled = true;
|
|
34
28
|
} catch (e) {
|
|
35
|
-
|
|
29
|
+
_percyInfo.default.enabled = false;
|
|
36
30
|
error = e;
|
|
37
31
|
}
|
|
38
32
|
|
|
39
|
-
if (
|
|
33
|
+
if (_percyInfo.default.enabled && _percyInfo.default.version.major !== 1) {
|
|
40
34
|
log.info('Unsupported Percy CLI version, disabling snapshots');
|
|
41
|
-
log.debug(`Found version: ${
|
|
42
|
-
|
|
43
|
-
} else if (!
|
|
35
|
+
log.debug(`Found version: ${_percyInfo.default.version}`);
|
|
36
|
+
_percyInfo.default.enabled = false;
|
|
37
|
+
} else if (!_percyInfo.default.enabled) {
|
|
44
38
|
log.info('Percy is not running, disabling snapshots');
|
|
45
39
|
log.debug(error);
|
|
46
40
|
}
|
|
47
41
|
|
|
48
|
-
if (
|
|
49
|
-
await
|
|
42
|
+
if (_percyInfo.default.enabled) {
|
|
43
|
+
await _logger.default.remote();
|
|
50
44
|
}
|
|
51
45
|
}
|
|
52
46
|
|
|
53
|
-
return
|
|
47
|
+
return _percyInfo.default.enabled;
|
|
54
48
|
}
|
|
55
|
-
|
|
49
|
+
|
|
50
|
+
var _default = isPercyEnabled;
|
|
51
|
+
exports.default = _default;
|
package/dist/percy-idle.js
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
exports.waitForPercyIdle = waitForPercyIdle;
|
|
8
|
+
|
|
9
|
+
var _request = _interopRequireDefault(require("./request.js"));
|
|
10
|
+
|
|
11
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
|
+
|
|
2
13
|
const RETRY_ERROR_CODES = ['ECONNRESET', 'ETIMEDOUT'];
|
|
3
|
-
|
|
14
|
+
|
|
15
|
+
async function waitForPercyIdle() {
|
|
4
16
|
try {
|
|
5
|
-
return !!(await
|
|
17
|
+
return !!(await (0, _request.default)('/percy/idle'));
|
|
6
18
|
} catch (e) {
|
|
7
19
|
return RETRY_ERROR_CODES.includes(e.code) && waitForPercyIdle();
|
|
8
20
|
}
|
|
9
21
|
}
|
|
10
|
-
|
|
22
|
+
|
|
23
|
+
var _default = waitForPercyIdle;
|
|
24
|
+
exports.default = _default;
|
package/dist/percy-info.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
1
8
|
// helper to create a version object from a string
|
|
2
9
|
function toVersion(str) {
|
|
3
10
|
str || (str = '0.0.0');
|
|
@@ -56,4 +63,5 @@ const info = {
|
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
};
|
|
59
|
-
|
|
66
|
+
var _default = info;
|
|
67
|
+
exports.default = _default;
|
package/dist/post-snapshot.js
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
exports.postSnapshot = postSnapshot;
|
|
8
|
+
|
|
9
|
+
var _percyInfo = _interopRequireDefault(require("./percy-info.js"));
|
|
10
|
+
|
|
11
|
+
var _request = _interopRequireDefault(require("./request.js"));
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
|
|
15
|
+
// Post snapshot data to the snapshot endpoint. If the snapshot endpoint responds with a closed
|
|
16
|
+
// error message, signal that Percy has been disabled.
|
|
17
|
+
async function postSnapshot(options, params) {
|
|
6
18
|
let query = params ? `?${new URLSearchParams(params)}` : '';
|
|
7
|
-
await
|
|
19
|
+
await _request.default.post(`/percy/snapshot${query}`, options).catch(err => {
|
|
8
20
|
var _err$response, _err$response$body, _err$response$body$bu;
|
|
9
21
|
|
|
10
22
|
if ((_err$response = err.response) !== null && _err$response !== void 0 && (_err$response$body = _err$response.body) !== null && _err$response$body !== void 0 && (_err$response$body$bu = _err$response$body.build) !== null && _err$response$body$bu !== void 0 && _err$response$body$bu.error) {
|
|
11
|
-
|
|
23
|
+
_percyInfo.default.enabled = false;
|
|
12
24
|
} else {
|
|
13
25
|
throw err;
|
|
14
26
|
}
|
|
15
27
|
});
|
|
16
28
|
}
|
|
17
|
-
|
|
29
|
+
|
|
30
|
+
var _default = postSnapshot;
|
|
31
|
+
exports.default = _default;
|
package/dist/request.js
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
exports.request = request;
|
|
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
|
+
// Helper to send a request to the local CLI API
|
|
18
|
+
async function request(path, options = {}) {
|
|
19
|
+
let response = await request.fetch(`${_percyInfo.default.address}${path}`, options); // maybe parse response body as json
|
|
5
20
|
|
|
6
21
|
if (typeof response.body === 'string' && response.headers['content-type'] === 'application/json') {
|
|
7
22
|
try {
|
|
@@ -46,7 +61,7 @@ if (process.env.__PERCY_BROWSERIFIED__) {
|
|
|
46
61
|
request.fetch = async function fetch(url, options) {
|
|
47
62
|
let {
|
|
48
63
|
default: http
|
|
49
|
-
} = await
|
|
64
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require('http')));
|
|
50
65
|
return new Promise((resolve, reject) => {
|
|
51
66
|
http.request(url, options).on('response', response => {
|
|
52
67
|
let body = '';
|
|
@@ -62,4 +77,5 @@ if (process.env.__PERCY_BROWSERIFIED__) {
|
|
|
62
77
|
};
|
|
63
78
|
}
|
|
64
79
|
|
|
65
|
-
|
|
80
|
+
var _default = request;
|
|
81
|
+
exports.default = _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@percy/sdk-utils",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
],
|
|
22
22
|
"main": "./dist/index.js",
|
|
23
23
|
"browser": "./dist/bundle.js",
|
|
24
|
-
"type": "module",
|
|
25
24
|
"exports": {
|
|
26
25
|
".": "./dist/index.js",
|
|
27
26
|
"./test/server": "./test/server.js",
|
|
@@ -47,18 +46,9 @@
|
|
|
47
46
|
},
|
|
48
47
|
"test": {
|
|
49
48
|
"external": [
|
|
50
|
-
"@percy/logger",
|
|
51
49
|
"test/server(.js)?"
|
|
52
|
-
]
|
|
53
|
-
"output": {
|
|
54
|
-
"globals": {
|
|
55
|
-
"@percy/logger": "PercySDKUtils.logger"
|
|
56
|
-
}
|
|
57
|
-
}
|
|
50
|
+
]
|
|
58
51
|
}
|
|
59
52
|
},
|
|
60
|
-
"
|
|
61
|
-
"@percy/logger": "1.1.0"
|
|
62
|
-
},
|
|
63
|
-
"gitHead": "bf551295a8a618502bb2db92ff302e19dc956b51"
|
|
53
|
+
"gitHead": "05f91ff29b613bde1c740c120c5d23a6722d3606"
|
|
64
54
|
}
|