MV3 Segment Fix (#16020)

feature/default_network_editable
Jyoti Puri 2 years ago committed by GitHub
parent d4de8eae9e
commit 6995174cbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      app/scripts/controllers/metametrics.js
  2. 275
      app/scripts/lib/segment/analytics.js
  3. 116
      app/scripts/lib/segment/analytics.test.js
  4. 4
      app/scripts/lib/segment/index.js
  5. 79
      lavamoat/browserify/beta/policy.json
  6. 79
      lavamoat/browserify/flask/policy.json
  7. 79
      lavamoat/browserify/main/policy.json
  8. 1445
      lavamoat/build-system/policy.json
  9. 4
      package.json
  10. 70
      yarn.lock

@ -65,7 +65,7 @@ const exceptionsToFilter = {
export default class MetaMetricsController {
/**
* @param {object} options
* @param {object} options.segment - an instance of analytics-node for tracking
* @param {object} options.segment - an instance of analytics for tracking
* events that conform to the new MetaMetrics tracking plan.
* @param {object} options.preferencesStore - The preferences controller store, used
* to access and subscribe to preferences that will be attached to events

@ -0,0 +1,275 @@
import removeSlash from 'remove-trailing-slash';
import looselyValidate from '@segment/loosely-validate-event';
import { isString } from 'lodash';
import isRetryAllowed from 'is-retry-allowed';
const noop = () => ({});
// Taken from https://stackoverflow.com/a/1349426/3696652
const characters =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const generateRandomId = () => {
let result = '';
const charactersLength = characters.length;
for (let i = 0; i < 20; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
};
// Method below is inspired from axios-retry https://github.com/softonic/axios-retry
function isNetworkError(error) {
return (
!error.response &&
Boolean(error.code) && // Prevents retrying cancelled requests
error.code !== 'ECONNABORTED' && // Prevents retrying timed out requests
isRetryAllowed(error)
); // Prevents retrying unsafe errors
}
export default class Analytics {
/**
* Initialize a new `Analytics` with Segment project's `writeKey` and an
* optional dictionary of `options`.
*
* @param {string} writeKey
* @param {object} [options] - (optional)
* @property {number} [flushAt] (default: 20)
* @property {number} [flushInterval] (default: 10000)
* @property {string} [host] (default: 'https://api.segment.io')
*/
constructor(writeKey, options = {}) {
this.writeKey = writeKey;
this.host = removeSlash(options.host || 'https://api.segment.io');
this.flushInterval = options.flushInterval || 10000;
this.flushAt = options.flushAt || Math.max(options.flushAt, 1) || 20;
this.queue = [];
this.path = '/v1/batch';
this.maxQueueSize = 1024 * 450;
this.flushed = false;
this.retryCount = 3;
Object.defineProperty(this, 'enable', {
configurable: false,
writable: false,
enumerable: true,
value: true,
});
}
_validate(message, type) {
looselyValidate(message, type);
}
_message(type, message, callback) {
this._validate(message, type);
this.enqueue(type, message, callback);
return this;
}
/**
* Send an identify `message`.
*
* @param {object} message
* @param {Function} [callback] - (optional)
* @returns {Analytics}
*/
identify(message, callback) {
return this._message('identify', message, callback);
}
/**
* Send a track `message`.
*
* @param {object} message
* @param {Function} [callback] - (optional)
* @returns {Analytics}
*/
track(message, callback) {
return this._message('track', message, callback);
}
/**
* Send a page `message`.
*
* @param {object} message
* @param {Function} [callback] - (optional)
* @returns {Analytics}
*/
page(message, callback) {
return this._message('page', message, callback);
}
/**
* Add a `message` of type `type` to the queue and
* check whether it should be flushed.
*
* @param {string} type
* @param {object} msg
* @param {Function} [callback] - (optional)
*/
enqueue(type, msg, callback = noop) {
if (!this.enable) {
setImmediate(callback);
return;
}
const message = { ...msg, type };
// Specifying library here helps segment to understand structure of request.
// Currently segment seems to support these source libraries only.
message.context = {
...message.context,
library: {
name: 'analytics-node',
},
};
if (!message.timestamp) {
message.timestamp = new Date();
}
if (!message.messageId) {
message.messageId = generateRandomId();
}
if (message.anonymousId && !isString(message.anonymousId)) {
message.anonymousId = JSON.stringify(message.anonymousId);
}
if (message.userId && !isString(message.userId)) {
message.userId = JSON.stringify(message.userId);
}
this.queue.push({ message, callback });
if (!this.flushed) {
this.flushed = true;
this.flush();
return;
}
const hasReachedFlushAt = this.queue.length >= this.flushAt;
const hasReachedQueueSize =
this.queue.reduce((acc, item) => acc + JSON.stringify(item).length, 0) >=
this.maxQueueSize;
if (hasReachedFlushAt || hasReachedQueueSize) {
this.flush();
}
if (this.flushInterval && !this.timer) {
this.timer = setTimeout(this.flush.bind(this), this.flushInterval);
}
}
/**
* Flush the current queue
*
* @param {Function} [callback] - (optional)
*/
flush(callback = noop) {
if (!this.enable) {
setImmediate(callback);
return Promise.resolve();
}
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
if (!this.queue.length) {
setImmediate(callback);
return Promise.resolve();
}
const items = this.queue.splice(0, this.flushAt);
const callbacks = items.map((item) => item.callback);
const messages = items.map((item) => item.message);
const data = {
batch: messages,
timestamp: new Date(),
sentAt: new Date(),
};
const done = (err) => {
setImmediate(() => {
callbacks.forEach((fn) => fn(err, data));
callback(err, data);
});
};
const headers = {
Authorization: `Basic ${Buffer.from(this.writeKey, 'utf8').toString(
'base64',
)}`,
};
return this._sendRequest(
`${this.host}${this.path}`,
{
method: 'POST',
body: JSON.stringify(data),
headers,
},
done,
0,
);
}
_retryRequest(url, body, done, retryNo) {
const delay = Math.pow(2, retryNo) * 100;
setTimeout(() => {
this._sendRequest(url, body, done, retryNo + 1);
}, delay);
}
async _sendRequest(url, body, done, retryNo) {
return fetch(url, body)
.then(async (response) => {
if (response.ok) {
done();
} else if (
this._isErrorRetryable({ response }) &&
retryNo <= this.retryCount
) {
this._retryRequest(url, body, done, retryNo);
} else {
const error = new Error(response.statusText);
done(error);
}
})
.catch((error) => {
if (this._isErrorRetryable(error) && retryNo <= this.retryCount) {
this._retryRequest(url, body, done, retryNo);
} else {
done(error);
}
});
}
_isErrorRetryable(error) {
// Retry Network Errors.
if (isNetworkError(error)) {
return true;
}
if (!error.response) {
// Cannot determine if the request can be retried
return false;
}
// Retry Server Errors (5xx).
if (error.response.status >= 500 && error.response.status <= 599) {
return true;
}
// Retry if rate limited.
if (error.response.status === 429) {
return true;
}
return false;
}
}

@ -0,0 +1,116 @@
import Analytics from './analytics';
const DUMMY_KEY = 'DUMMY_KEY';
const DUMMY_MESSAGE = {
userId: 'userId',
idValue: 'idValue',
event: 'event',
};
const FLUSH_INTERVAL = 10000;
global.setImmediate = (arg) => {
arg();
};
global.fetch = () =>
Promise.resolve({
ok: true,
json: () => Promise.resolve({ success: true }),
});
describe('Analytics', function () {
let analytics;
beforeEach(() => {
analytics = new Analytics(DUMMY_KEY);
});
describe('#flush', function () {
it('first message is immediately flushed', function () {
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(0);
expect(mock).toHaveBeenCalledTimes(1);
});
it('after first message it is called when queue size equals flushAt value', function () {
analytics = new Analytics(DUMMY_KEY, { flushAt: 3 });
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(0);
expect(mock).toHaveBeenCalledTimes(2);
});
it('except for first message it is called until queue size is less than flushAt value', function () {
analytics = new Analytics(DUMMY_KEY, { flushAt: 3 });
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(2);
expect(mock).toHaveBeenCalledTimes(1);
});
it('after first message it is called after flushInterval is elapsed', function () {
jest.useFakeTimers();
analytics = new Analytics(DUMMY_KEY, { flushInterval: FLUSH_INTERVAL });
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
jest.advanceTimersByTime(FLUSH_INTERVAL);
expect(analytics.queue).toHaveLength(0);
expect(mock).toHaveBeenCalledTimes(2);
});
it('after first message it is not called until flushInterval is elapsed', function () {
jest.useFakeTimers();
analytics = new Analytics(DUMMY_KEY, { flushInterval: FLUSH_INTERVAL });
const mock = jest.fn(analytics.flush);
analytics.flush = mock;
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
jest.advanceTimersByTime(FLUSH_INTERVAL - 100);
expect(analytics.queue).toHaveLength(1);
expect(mock).toHaveBeenCalledTimes(1);
});
it('invokes callbacks', async function () {
const callback = jest.fn();
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE, callback);
await analytics.flush();
expect(callback).toHaveBeenCalledTimes(1);
});
});
describe('#track', function () {
it('adds messages to ququq', function () {
analytics.track(DUMMY_MESSAGE);
analytics.track(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(1);
});
});
describe('#page', function () {
it('adds messages to ququq', function () {
analytics.page(DUMMY_MESSAGE);
analytics.page(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(1);
});
});
describe('#identify', function () {
it('adds messages to ququq', function () {
analytics.identify(DUMMY_MESSAGE);
analytics.identify(DUMMY_MESSAGE);
expect(analytics.queue).toHaveLength(1);
});
});
});

@ -1,5 +1,5 @@
import Analytics from 'analytics-node';
import { SECOND } from '../../../shared/constants/time';
import { SECOND } from '../../../../shared/constants/time';
import Analytics from './analytics';
const SEGMENT_WRITE_KEY = process.env.SEGMENT_WRITE_KEY ?? null;
const SEGMENT_HOST = process.env.SEGMENT_HOST ?? null;

@ -1430,8 +1430,8 @@
"process": true
},
"packages": {
"analytics-node>ms": true,
"browserify>process": true
"browserify>process": true,
"gulp-livereload>debug>ms": true
}
},
"3box>ipfs>libp2p-websocket-star-multi>libp2p-websocket-star>socket.io-pull-stream>uuid": {
@ -1859,7 +1859,7 @@
"setTimeout": true
},
"packages": {
"analytics-node>ms": true
"gulp-livereload>debug>ms": true
}
},
"3box>ipfs>stream-to-pull-stream": {
@ -3540,6 +3540,14 @@
"redux-thunk": true
}
},
"@segment/loosely-validate-event": {
"packages": {
"@segment/loosely-validate-event>component-type": true,
"@segment/loosely-validate-event>join-component": true,
"browserify>assert": true,
"browserify>buffer": true
}
},
"@sentry/browser": {
"globals": {
"XMLHttpRequest": true,
@ -3971,71 +3979,6 @@
"pumpify>inherits": true
}
},
"analytics-node": {
"globals": {
"clearTimeout": true,
"console.log": true,
"setImmediate": true,
"setTimeout": true
},
"packages": {
"analytics-node>@segment/loosely-validate-event": true,
"analytics-node>axios": true,
"analytics-node>axios-retry": true,
"analytics-node>lodash.isstring": true,
"analytics-node>md5": true,
"analytics-node>ms": true,
"analytics-node>remove-trailing-slash": true,
"analytics-node>uuid": true,
"browserify>assert": true,
"browserify>process": true
}
},
"analytics-node>@segment/loosely-validate-event": {
"packages": {
"analytics-node>@segment/loosely-validate-event>component-type": true,
"analytics-node>@segment/loosely-validate-event>join-component": true,
"browserify>assert": true,
"browserify>buffer": true
}
},
"analytics-node>axios": {
"globals": {
"FormData": true,
"URLSearchParams": true,
"XMLHttpRequest": true,
"btoa": true,
"console.warn": true,
"document": true,
"location.href": true,
"navigator": true,
"setTimeout": true
},
"packages": {
"browserify>process": true
}
},
"analytics-node>axios-retry": {
"globals": {
"setTimeout": true
},
"packages": {
"geckodriver>got>is-retry-allowed": true
}
},
"analytics-node>md5": {
"packages": {
"analytics-node>md5>charenc": true,
"analytics-node>md5>crypt": true,
"browserify>insert-module-globals>is-buffer": true
}
},
"analytics-node>uuid": {
"globals": {
"crypto": true,
"msCrypto": true
}
},
"await-semaphore": {
"packages": {
"browserify>process": true,

@ -1430,8 +1430,8 @@
"process": true
},
"packages": {
"analytics-node>ms": true,
"browserify>process": true
"browserify>process": true,
"gulp-livereload>debug>ms": true
}
},
"3box>ipfs>libp2p-websocket-star-multi>libp2p-websocket-star>socket.io-pull-stream>uuid": {
@ -1859,7 +1859,7 @@
"setTimeout": true
},
"packages": {
"analytics-node>ms": true
"gulp-livereload>debug>ms": true
}
},
"3box>ipfs>stream-to-pull-stream": {
@ -4332,6 +4332,14 @@
"redux-thunk": true
}
},
"@segment/loosely-validate-event": {
"packages": {
"@segment/loosely-validate-event>component-type": true,
"@segment/loosely-validate-event>join-component": true,
"browserify>assert": true,
"browserify>buffer": true
}
},
"@sentry/browser": {
"globals": {
"XMLHttpRequest": true,
@ -4763,71 +4771,6 @@
"pumpify>inherits": true
}
},
"analytics-node": {
"globals": {
"clearTimeout": true,
"console.log": true,
"setImmediate": true,
"setTimeout": true
},
"packages": {
"analytics-node>@segment/loosely-validate-event": true,
"analytics-node>axios": true,
"analytics-node>axios-retry": true,
"analytics-node>lodash.isstring": true,
"analytics-node>md5": true,
"analytics-node>ms": true,
"analytics-node>remove-trailing-slash": true,
"analytics-node>uuid": true,
"browserify>assert": true,
"browserify>process": true
}
},
"analytics-node>@segment/loosely-validate-event": {
"packages": {
"analytics-node>@segment/loosely-validate-event>component-type": true,
"analytics-node>@segment/loosely-validate-event>join-component": true,
"browserify>assert": true,
"browserify>buffer": true
}
},
"analytics-node>axios": {
"globals": {
"FormData": true,
"URLSearchParams": true,
"XMLHttpRequest": true,
"btoa": true,
"console.warn": true,
"document": true,
"location.href": true,
"navigator": true,
"setTimeout": true
},
"packages": {
"browserify>process": true
}
},
"analytics-node>axios-retry": {
"globals": {
"setTimeout": true
},
"packages": {
"geckodriver>got>is-retry-allowed": true
}
},
"analytics-node>md5": {
"packages": {
"analytics-node>md5>charenc": true,
"analytics-node>md5>crypt": true,
"browserify>insert-module-globals>is-buffer": true
}
},
"analytics-node>uuid": {
"globals": {
"crypto": true,
"msCrypto": true
}
},
"await-semaphore": {
"packages": {
"browserify>process": true,

@ -1430,8 +1430,8 @@
"process": true
},
"packages": {
"analytics-node>ms": true,
"browserify>process": true
"browserify>process": true,
"gulp-livereload>debug>ms": true
}
},
"3box>ipfs>libp2p-websocket-star-multi>libp2p-websocket-star>socket.io-pull-stream>uuid": {
@ -1859,7 +1859,7 @@
"setTimeout": true
},
"packages": {
"analytics-node>ms": true
"gulp-livereload>debug>ms": true
}
},
"3box>ipfs>stream-to-pull-stream": {
@ -3540,6 +3540,14 @@
"redux-thunk": true
}
},
"@segment/loosely-validate-event": {
"packages": {
"@segment/loosely-validate-event>component-type": true,
"@segment/loosely-validate-event>join-component": true,
"browserify>assert": true,
"browserify>buffer": true
}
},
"@sentry/browser": {
"globals": {
"XMLHttpRequest": true,
@ -3971,71 +3979,6 @@
"pumpify>inherits": true
}
},
"analytics-node": {
"globals": {
"clearTimeout": true,
"console.log": true,
"setImmediate": true,
"setTimeout": true
},
"packages": {
"analytics-node>@segment/loosely-validate-event": true,
"analytics-node>axios": true,
"analytics-node>axios-retry": true,
"analytics-node>lodash.isstring": true,
"analytics-node>md5": true,
"analytics-node>ms": true,
"analytics-node>remove-trailing-slash": true,
"analytics-node>uuid": true,
"browserify>assert": true,
"browserify>process": true
}
},
"analytics-node>@segment/loosely-validate-event": {
"packages": {
"analytics-node>@segment/loosely-validate-event>component-type": true,
"analytics-node>@segment/loosely-validate-event>join-component": true,
"browserify>assert": true,
"browserify>buffer": true
}
},
"analytics-node>axios": {
"globals": {
"FormData": true,
"URLSearchParams": true,
"XMLHttpRequest": true,
"btoa": true,
"console.warn": true,
"document": true,
"location.href": true,
"navigator": true,
"setTimeout": true
},
"packages": {
"browserify>process": true
}
},
"analytics-node>axios-retry": {
"globals": {
"setTimeout": true
},
"packages": {
"geckodriver>got>is-retry-allowed": true
}
},
"analytics-node>md5": {
"packages": {
"analytics-node>md5>charenc": true,
"analytics-node>md5>crypt": true,
"browserify>insert-module-globals>is-buffer": true
}
},
"analytics-node>uuid": {
"globals": {
"crypto": true,
"msCrypto": true
}
},
"await-semaphore": {
"packages": {
"browserify>process": true,

File diff suppressed because it is too large Load Diff

@ -143,6 +143,7 @@
"@ngraveio/bc-ur": "^1.1.6",
"@popperjs/core": "^2.4.0",
"@reduxjs/toolkit": "^1.6.2",
"@segment/loosely-validate-event": "^2.0.0",
"@sentry/browser": "^6.0.0",
"@sentry/integrations": "^6.0.0",
"@sentry/types": "^6.0.1",
@ -152,7 +153,6 @@
"@truffle/decoder": "^5.1.0",
"@zxing/browser": "^0.0.10",
"@zxing/library": "0.8.0",
"analytics-node": "^3.4.0-beta.3",
"await-semaphore": "^0.1.1",
"base32-encode": "^1.2.0",
"base64-js": "^1.5.1",
@ -189,6 +189,7 @@
"globalthis": "^1.0.1",
"human-standard-token-abi": "^2.0.0",
"immer": "^9.0.6",
"is-retry-allowed": "^2.2.0",
"jest-junit": "^14.0.1",
"json-rpc-engine": "^6.1.0",
"json-rpc-middleware-stream": "^2.1.1",
@ -226,6 +227,7 @@
"readable-stream": "^2.3.3",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0",
"remove-trailing-slash": "^0.1.1",
"reselect": "^3.0.1",
"safe-event-emitter": "^1.0.1",
"ses": "^0.12.4",

@ -6632,20 +6632,6 @@ amdefine@>=0.0.4:
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
analytics-node@^3.4.0-beta.3:
version "3.4.0-beta.3"
resolved "https://registry.yarnpkg.com/analytics-node/-/analytics-node-3.4.0-beta.3.tgz#5eb0694598cff493c64faf5efc1225533a253f13"
integrity sha512-NIdpxiwlZ4cKgs9MDlDe89b5bg/pMq2W7XTA+cjzCM66IwW3ujZhVE49vk+zG6Yrxk0s/DXmennJ+cCQIsTKMA==
dependencies:
"@segment/loosely-validate-event" "^2.0.0"
axios "^0.19.2"
axios-retry "^3.0.2"
lodash.isstring "^4.0.1"
md5 "^2.2.1"
ms "^2.0.0"
remove-trailing-slash "^0.1.0"
uuid "^3.2.1"
ansi-align@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
@ -7337,14 +7323,7 @@ axe-core@^4.2.0:
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.3.tgz#b55cd8e8ddf659fe89b064680e1c6a4dceab0325"
integrity sha512-/lqqLAmuIPi79WYfRpy2i8z+x+vxU3zX2uAm0gs1q52qTuKwolOj1P8XbufpXcsydrpKx2yGn2wzAnxCMV86QA==
axios-retry@^3.0.2:
version "3.1.8"
resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.1.8.tgz#ffcfed757e1fab8cbf832f8505bb0e0af47c520c"
integrity sha512-yPw5Y4Bg6Dgmhm35KaJFtlh23s1TecW0HsUerK4/IS1UKl0gtN2aJqdEKtVomiOS/bDo5w4P3sqgki/M10eF8Q==
dependencies:
is-retry-allowed "^1.1.0"
axios@^0.19.2, axios@^0.21.2:
axios@^0.21.2:
version "0.21.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
@ -8902,11 +8881,6 @@ character-reference-invalid@^1.0.0:
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.1.tgz#942835f750e4ec61a308e60c2ef8cc1011202efc"
integrity sha1-lCg191Dk7GGjCOYMLvjMEBEgLvw=
charenc@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
check-error@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
@ -9936,11 +9910,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
crypt@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
crypto-browserify@^3.0.0, crypto-browserify@^3.11.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@ -13493,9 +13462,9 @@ fnv1a@^1.0.1:
integrity sha1-kV4tbQI8Q9UiStn20qPEFW9XEvU=
follow-redirects@^1.14.0, follow-redirects@^1.14.9:
version "1.15.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
for-each@^0.3.3:
version "0.3.3"
@ -16198,7 +16167,7 @@ is-boolean-object@^1.0.0, is-boolean-object@^1.1.0:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
is-buffer@^1.0.2, is-buffer@^1.1.0, is-buffer@^1.1.5, is-buffer@~1.1.6:
is-buffer@^1.0.2, is-buffer@^1.1.0, is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
@ -16676,11 +16645,16 @@ is-relative@^1.0.0:
dependencies:
is-unc-path "^1.0.0"
is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
is-retry-allowed@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
is-retry-allowed@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz#88f34cbd236e043e71b6932d09b0c65fb7b4d71d"
integrity sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==
is-shared-array-buffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
@ -19202,11 +19176,6 @@ lodash.isplainobject@^4.0.6:
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
lodash.isstring@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
lodash.map@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
@ -19581,15 +19550,6 @@ md5.js@^1.3.4:
inherits "^2.0.1"
safe-buffer "^5.1.2"
md5@^2.2.1:
version "2.3.0"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
integrity sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==
dependencies:
charenc "0.0.2"
crypt "0.0.2"
is-buffer "~1.1.6"
mdast-squeeze-paragraphs@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97"
@ -24600,10 +24560,10 @@ remove-trailing-separator@^1.0.1, remove-trailing-separator@^1.1.0:
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
remove-trailing-slash@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-slash/-/remove-trailing-slash-0.1.0.tgz#1498e5df0984c27e49b76ebf06887ca2d01150d2"
integrity sha1-FJjl3wmEwn5Jt26/Boh8otARUNI=
remove-trailing-slash@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/remove-trailing-slash/-/remove-trailing-slash-0.1.1.tgz#be2285a59f39c74d1bce4f825950061915e3780d"
integrity sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==
renderkid@^2.0.1:
version "2.0.3"

Loading…
Cancel
Save