blacklist sync
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Timo Hocker 2022-08-27 16:39:07 +02:00
parent e80e3f9a94
commit 31f739d4b8
Signed by: Timo
GPG Key ID: DFAC2CF4E1D1BEC9
15 changed files with 271 additions and 207 deletions

View File

@ -1,5 +1,11 @@
# Changelog
## 4.0.0
- Blacklist entries can now be synchronized through redis
BREAKING: Blacklist functions are now asynchronous
## 3.3.0
- Verification Keys can now be synchronized through redis

View File

@ -1,6 +1,6 @@
# auth-server-helper
version: 3.3.x
version: 4.0.x
customizable and simple authentication
@ -165,7 +165,7 @@ For Documentation on the different Cookie Attributes see <https://developer.mozi
```js
const {blacklist} = require('@sapphirecode/auth-server-helper');
blacklist.add_signature(token_id); // the token id is returned from any function that creates tokens
await blacklist.add_signature(token_id); // the token id is returned from any function that creates tokens
```
#### Logout function
@ -228,10 +228,10 @@ const {keystore, blacklist} = require('@sapphirecode/auth-server-helper');
keystore.reset_instance();
// clear blacklist
blacklist.clear();
await blacklist.clear();
// clear blacklist items older than 10 seconds
blacklist.clear(Date.now() - 10000);
await blacklist.clear(Date.now() - 10000);
```
## License

View File

@ -74,7 +74,7 @@ class Authority {
log ('parsing token %s %s', result.type, result.id);
if (!blacklist.is_valid (data.id)) {
if (!(await blacklist.is_valid (data.id))) {
log ('token is blacklisted');
result.error = 'blacklisted';
return result;

View File

@ -6,6 +6,7 @@
*/
import { debug } from './debug';
import { redis_blacklist_store } from './RedisData/RedisBlacklistStore';
const logger = debug ('blacklist');
@ -21,24 +22,31 @@ class Blacklist {
this._signatures = [];
}
public clear (before: number = Number.POSITIVE_INFINITY): void {
public async clear (
before: number = Number.POSITIVE_INFINITY
): Promise<void> {
logger.extend ('clear') ('clearing blacklist');
for (let i = this._signatures.length - 1; i >= 0; i--) {
if (this._signatures[i].iat < before)
this.remove_signature (i);
if (this._signatures[i].iat < before) {
// eslint-disable-next-line no-await-in-loop
await this.remove_signature (i);
}
}
}
public add_signature (hash: string): void {
public async add_signature (hash: string): Promise<void> {
logger.extend ('add_signature') ('blacklisting signature %s', hash);
this._signatures.push ({ iat: Date.now (), hash });
await redis_blacklist_store.add (hash);
}
public remove_signature (signature: number | string): void {
public async remove_signature (signature: number | string): Promise<void> {
const log = logger.extend ('remove_signature');
log ('removing signature from blacklist %s', signature);
let key = '';
if (typeof signature === 'string') {
log ('received string, searching through signatures');
key = signature;
for (let i = this._signatures.length - 1; i >= 0; i--) {
if (this._signatures[i].hash === signature)
this._signatures.splice (i, 1);
@ -46,11 +54,13 @@ class Blacklist {
}
else {
log ('received index, removing at index');
key = this._signatures[signature].hash;
this._signatures.splice (signature, 1);
}
await redis_blacklist_store.remove (key);
}
public is_valid (hash: string): boolean {
public async is_valid (hash: string): Promise<boolean> {
const log = logger.extend ('is_valid');
log ('checking signature for blacklist entry %s', hash);
for (const sig of this._signatures) {
@ -60,6 +70,12 @@ class Blacklist {
}
}
log ('signature is not blacklisted locally, checking redis');
if (await redis_blacklist_store.get (hash)) {
log ('signature is blacklisted in redis');
return false;
}
log ('signature is not blacklisted');
return true;
}
@ -76,6 +92,10 @@ class Blacklist {
);
this._signatures.push (...data);
}
public sync_redis (url: string): void {
redis_blacklist_store.connect (url);
}
}
const bl = (new Blacklist);

View File

@ -209,8 +209,10 @@ class GatewayClass {
log ('found %d tokens: %O', tokens.length, tokens);
for (const token of tokens)
blacklist.add_signature (token.id);
for (const token of tokens) {
// eslint-disable-next-line no-await-in-loop
await blacklist.add_signature (token.id);
}
log ('complete');
}

View File

@ -9,7 +9,6 @@ import { generate_keypair, random_hex } from '@sapphirecode/crypto-helper';
import { to_b58 } from '@sapphirecode/encoding-helper';
import { debug } from './debug';
import { KeyStoreData, KeyStoreExport } from './Key';
import { redis } from './Redis';
import { redis_key_store } from './RedisData/RedisKeyStore';
const logger = debug ('keystore');
@ -20,7 +19,6 @@ class KeyStore {
private _keys: KeyStoreData = {};
private _interval: NodeJS.Timeout;
private _instance: string;
private _sync_redis = false;
public get instance_id (): string {
return this._instance;
@ -58,8 +56,7 @@ class KeyStore {
valid_until: time + (valid_for * 1000)
}
};
if (this._sync_redis)
await redis_key_store.set ({ ...result.public_key, index });
await redis_key_store.set ({ ...result.public_key, index });
this._keys[index] = result;
}
@ -135,11 +132,11 @@ class KeyStore {
let key = null;
if (typeof this._keys[index] === 'undefined') {
if (this._sync_redis)
key = await redis_key_store.get (index);
}
else { key = this._keys[index].public_key; }
if (typeof this._keys[index] === 'undefined')
key = await redis_key_store.get (index);
else
key = this._keys[index].public_key;
if (key === null)
throw new Error ('key could not be found');
@ -182,13 +179,11 @@ class KeyStore {
logger.extend ('reset_instance') ('resetting keystore');
this._instance = to_b58 (random_hex (16), 'hex');
this._keys = {};
this._sync_redis = false;
redis.disconnect ();
redis_key_store.disconnect ();
}
public sync_redis (url: string): void {
redis.connect (url);
this._sync_redis = true;
redis_key_store.connect (url);
}
}

View File

@ -51,16 +51,14 @@ export class Redis {
log ('done');
}
public get redis (): IORedis {
protected get redis (): IORedis {
if (this._redis === null)
throw new Error ('redis is not connected');
return this._redis;
}
public get is_active (): boolean {
protected get is_active (): boolean {
return this._redis !== null;
}
}
export const redis = (new Redis);

View File

@ -6,31 +6,44 @@
*/
import { debug } from '../debug';
import { redis } from '../Redis';
import { Redis } from '../Redis';
const logger = debug ('RedisBlacklistStore');
export class RedisBlacklistStore {
export class RedisBlacklistStore extends Redis {
public async add (key: string): Promise<void> {
const log = logger.extend ('set');
log ('trying to add key %s to redis blacklist', key);
if (!redis.is_active) {
if (!this.is_active) {
log ('redis is inactive, skipping');
return;
}
await redis.redis.sadd ('blacklist', key);
await this.redis.sadd ('blacklist', key);
log ('saved key');
}
public async remove (key: string): Promise<void> {
const log = logger.extend ('remove');
log ('removing key %s from redis', key);
if (!this.is_active) {
log ('redis is inactive, skipping');
return;
}
await this.redis.srem ('blacklist', key);
log ('removed key');
}
public async get (key: string): Promise<boolean> {
const log = logger.extend ('get');
log ('trying to find key %s in redis blacklist', key);
if (!redis.is_active) {
if (!this.is_active) {
log ('redis is inactive, skipping');
return false;
}
const res = await redis.redis.sismember ('blacklist', key) === 1;
const res = await this.redis.sismember ('blacklist', key) === 1;
log ('found key %s', res);
return res;
}
}
export const redis_blacklist_store = new RedisBlacklistStore;

View File

@ -7,15 +7,15 @@
import { debug } from '../debug';
import { LabelledKey } from '../Key';
import { redis } from '../Redis';
import { Redis } from '../Redis';
const logger = debug ('RedisKeyStore');
export class RedisKeyStore {
export class RedisKeyStore extends Redis {
public async set (value: LabelledKey): Promise<void> {
const log = logger.extend ('set');
log ('trying to set key %s to redis', value.index);
if (!redis.is_active) {
if (!this.is_active) {
log ('redis is inactive, skipping');
return;
}
@ -24,7 +24,7 @@ export class RedisKeyStore {
.getTime ()) / 1000
);
log ('key is valid for %d seconds', valid_for);
await redis.redis.setex (
await this.redis.setex (
`keystore_${value.index}`,
valid_for,
JSON.stringify (value)
@ -35,11 +35,11 @@ export class RedisKeyStore {
public async get (index: string): Promise<LabelledKey | null> {
const log = logger.extend ('get');
log ('trying to get key %s from redis', index);
if (!redis.is_active) {
if (!this.is_active) {
log ('redis is inactive, skipping');
return null;
}
const res = await redis.redis.get (`keystore_${index}`);
const res = await this.redis.get (`keystore_${index}`);
if (res === null) {
log ('key not found in redis');
return null;

View File

@ -1,6 +1,6 @@
{
"name": "@sapphirecode/auth-server-helper",
"version": "3.3.3",
"version": "4.0.0",
"main": "dist/lib/index.js",
"author": {
"name": "Timo Hocker",

View File

@ -104,7 +104,7 @@ describe ('authority', () => {
const token = await auth.sign ('access_token', 60);
jasmine.clock ()
.tick (30000);
bl.add_signature (token.id);
await bl.add_signature (token.id);
const res = await auth.verify (token.signature);
expect (res.authorized)
.toBeFalse ();
@ -144,7 +144,7 @@ describe ('authority', () => {
const token = await auth.sign ('refresh_token', 600);
jasmine.clock ()
.tick (30000);
bl.add_signature (token.id);
await bl.add_signature (token.id);
const res = await auth.verify (token.signature);
expect (res.authorized)
.toBeFalse ();

View File

@ -18,70 +18,70 @@ describe ('blacklist', () => {
clock_finalize ();
});
it ('should validate any string', () => {
expect (blacklist.is_valid ('foo'))
it ('should validate any string', async () => {
expect (await blacklist.is_valid ('foo'))
.toBeTrue ();
expect (blacklist.is_valid ('bar'))
expect (await blacklist.is_valid ('bar'))
.toBeTrue ();
expect (blacklist.is_valid ('baz'))
expect (await blacklist.is_valid ('baz'))
.toBeTrue ();
});
it ('should blacklist strings', () => {
blacklist.add_signature ('foo');
blacklist.add_signature ('bar');
expect (blacklist.is_valid ('foo'))
it ('should blacklist strings', async () => {
await blacklist.add_signature ('foo');
await blacklist.add_signature ('bar');
expect (await blacklist.is_valid ('foo'))
.toBeFalse ();
expect (blacklist.is_valid ('bar'))
expect (await blacklist.is_valid ('bar'))
.toBeFalse ();
expect (blacklist.is_valid ('baz'))
expect (await blacklist.is_valid ('baz'))
.toBeTrue ();
});
it ('should remove one string', () => {
blacklist.remove_signature ('foo');
expect (blacklist.is_valid ('foo'))
it ('should remove one string', async () => {
await blacklist.remove_signature ('foo');
expect (await blacklist.is_valid ('foo'))
.toBeTrue ();
expect (blacklist.is_valid ('bar'))
expect (await blacklist.is_valid ('bar'))
.toBeFalse ();
expect (blacklist.is_valid ('baz'))
expect (await blacklist.is_valid ('baz'))
.toBeTrue ();
});
it ('should clear after time', () => {
it ('should clear after time', async () => {
jasmine.clock ()
.tick (5000);
blacklist.add_signature ('baz');
blacklist.clear (Date.now () - 100);
expect (blacklist.is_valid ('foo'))
await blacklist.add_signature ('baz');
await blacklist.clear (Date.now () - 100);
expect (await blacklist.is_valid ('foo'))
.toBeTrue ();
expect (blacklist.is_valid ('bar'))
expect (await blacklist.is_valid ('bar'))
.toBeTrue ();
expect (blacklist.is_valid ('baz'))
expect (await blacklist.is_valid ('baz'))
.toBeFalse ();
});
it ('should clear all', () => {
blacklist.add_signature ('foo');
blacklist.add_signature ('bar');
blacklist.add_signature ('baz');
expect (blacklist.is_valid ('foo'))
it ('should clear all', async () => {
await blacklist.add_signature ('foo');
await blacklist.add_signature ('bar');
await blacklist.add_signature ('baz');
expect (await blacklist.is_valid ('foo'))
.toBeFalse ();
expect (blacklist.is_valid ('bar'))
expect (await blacklist.is_valid ('bar'))
.toBeFalse ();
expect (blacklist.is_valid ('baz'))
expect (await blacklist.is_valid ('baz'))
.toBeFalse ();
blacklist.clear ();
expect (blacklist.is_valid ('foo'))
await blacklist.clear ();
expect (await blacklist.is_valid ('foo'))
.toBeTrue ();
expect (blacklist.is_valid ('bar'))
expect (await blacklist.is_valid ('bar'))
.toBeTrue ();
expect (blacklist.is_valid ('baz'))
expect (await blacklist.is_valid ('baz'))
.toBeTrue ();
});
it ('should export and import data', () => {
blacklist.add_signature ('baz');
it ('should export and import data', async () => {
await blacklist.add_signature ('baz');
const exp = blacklist.export_blacklist ();
// eslint-disable-next-line dot-notation
expect (blacklist['_signatures'])

View File

@ -127,7 +127,7 @@ describe ('gateway', () => {
it ('should reject a blacklisted access token', async () => {
const token = await authority.sign ('access_token', 60);
blacklist.add_signature (token.id);
await blacklist.add_signature (token.id);
const resp = await get ({ authorization: `Bearer ${token.signature}` });
expect (resp.statusCode)
.toEqual (302);

View File

@ -5,17 +5,25 @@
* Created by Timo Hocker <timo@scode.ovh>, August 2022
*/
/* eslint-disable dot-notation */
import { blacklist } from '../../lib';
import ks from '../../lib/KeyStore';
import { redis } from '../../lib/Redis';
import { Redis } from '../../lib/Redis';
import { clock_finalize, clock_setup } from '../Helper';
const frame = 3600;
const redis_url = process.env.TEST_REDIS_URL || 'redis://localhost';
const redis = new Redis;
redis.connect (redis_url);
// eslint-disable-next-line max-lines-per-function
describe ('redis', () => {
beforeAll (() => {
beforeAll (async () => {
ks.reset_instance ();
ks.sync_redis (redis_url);
await blacklist.clear ();
blacklist.sync_redis (redis_url);
clock_setup ();
});
@ -48,11 +56,9 @@ describe ('redis', () => {
});
it ('should have two keys in redis', async () => {
// eslint-disable-next-line dot-notation
expect (JSON.parse (await redis['_redis']
?.get (`keystore_${i1}`) as string).key)
.toEqual (k1);
// eslint-disable-next-line dot-notation
expect (JSON.parse (await redis['_redis']
?.get (`keystore_${i2}`) as string).key)
.toEqual (k2);
@ -72,4 +78,28 @@ describe ('redis', () => {
expect (await ks.get_key (iat2, old_instance))
.toEqual (k2);
});
it ('should add two keys to the blacklist', async () => {
await blacklist.add_signature ('test');
await blacklist.add_signature ('foo');
});
it ('should have two keys in redis blacklist', async () => {
expect ((await redis['_redis']?.sismember ('blacklist', 'test')) === 1)
.toBeTrue ();
expect ((await redis['_redis']?.sismember ('blacklist', 'foo')) === 1)
.toBeTrue ();
expect ((await redis['_redis']?.sismember ('blacklist', 'bar')) === 1)
.toBeFalse ();
});
it ('should read keys from redis', async () => {
blacklist['_signatures'].splice (0, blacklist['_signatures'].length);
expect (await blacklist.is_valid ('test'))
.toBeFalse ();
expect (await blacklist.is_valid ('foo'))
.toBeFalse ();
expect (await blacklist.is_valid ('bar'))
.toBeTrue ();
});
});

244
yarn.lock
View File

@ -18,37 +18,37 @@
"@babel/highlight" "^7.18.6"
"@babel/compat-data@^7.18.8":
version "7.18.8"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d"
integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==
version "7.18.13"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.13.tgz#6aff7b350a1e8c3e40b029e46cbe78e24a913483"
integrity sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==
"@babel/core@^7.7.5", "@babel/core@~7.18.0":
version "7.18.10"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8"
integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==
version "7.18.13"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.13.tgz#9be8c44512751b05094a4d3ab05fc53a47ce00ac"
integrity sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==
dependencies:
"@ampproject/remapping" "^2.1.0"
"@babel/code-frame" "^7.18.6"
"@babel/generator" "^7.18.10"
"@babel/generator" "^7.18.13"
"@babel/helper-compilation-targets" "^7.18.9"
"@babel/helper-module-transforms" "^7.18.9"
"@babel/helpers" "^7.18.9"
"@babel/parser" "^7.18.10"
"@babel/parser" "^7.18.13"
"@babel/template" "^7.18.10"
"@babel/traverse" "^7.18.10"
"@babel/types" "^7.18.10"
"@babel/traverse" "^7.18.13"
"@babel/types" "^7.18.13"
convert-source-map "^1.7.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
json5 "^2.2.1"
semver "^6.3.0"
"@babel/generator@^7.18.10", "@babel/generator@~7.18.0":
version "7.18.12"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.12.tgz#fa58daa303757bd6f5e4bbca91b342040463d9f4"
integrity sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==
"@babel/generator@^7.18.13", "@babel/generator@~7.18.0":
version "7.18.13"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.13.tgz#59550cbb9ae79b8def15587bdfbaa388c4abf212"
integrity sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==
dependencies:
"@babel/types" "^7.18.10"
"@babel/types" "^7.18.13"
"@jridgewell/gen-mapping" "^0.3.2"
jsesc "^2.5.1"
@ -70,9 +70,9 @@
semver "^6.3.0"
"@babel/helper-create-class-features-plugin@^7.17.12", "@babel/helper-create-class-features-plugin@^7.18.9":
version "7.18.9"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce"
integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw==
version "7.18.13"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.13.tgz#63e771187bd06d234f95fdf8bd5f8b6429de6298"
integrity sha512-hDvXp+QYxSRL+23mpAlSGxHMDyIGChm0/AwTfTAAK5Ufe40nCsyNdaYCGuK91phn/fVu9kqayImRDkvNAgdrsA==
dependencies:
"@babel/helper-annotate-as-pure" "^7.18.6"
"@babel/helper-environment-visitor" "^7.18.9"
@ -200,10 +200,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/parser@^7.18.10", "@babel/parser@^7.18.11", "@babel/parser@~7.18.0":
version "7.18.11"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9"
integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==
"@babel/parser@^7.18.10", "@babel/parser@^7.18.13", "@babel/parser@~7.18.0":
version "7.18.13"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.13.tgz#5b2dd21cae4a2c5145f1fbd8ca103f9313d3b7e4"
integrity sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==
"@babel/plugin-proposal-class-properties@~7.17.0":
version "7.17.12"
@ -273,26 +273,26 @@
"@babel/parser" "^7.18.10"
"@babel/types" "^7.18.10"
"@babel/traverse@^7.18.10", "@babel/traverse@^7.18.9":
version "7.18.11"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.11.tgz#3d51f2afbd83ecf9912bcbb5c4d94e3d2ddaa16f"
integrity sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==
"@babel/traverse@^7.18.13", "@babel/traverse@^7.18.9":
version "7.18.13"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.13.tgz#5ab59ef51a997b3f10c4587d648b9696b6cb1a68"
integrity sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==
dependencies:
"@babel/code-frame" "^7.18.6"
"@babel/generator" "^7.18.10"
"@babel/generator" "^7.18.13"
"@babel/helper-environment-visitor" "^7.18.9"
"@babel/helper-function-name" "^7.18.9"
"@babel/helper-hoist-variables" "^7.18.6"
"@babel/helper-split-export-declaration" "^7.18.6"
"@babel/parser" "^7.18.11"
"@babel/types" "^7.18.10"
"@babel/parser" "^7.18.13"
"@babel/types" "^7.18.13"
debug "^4.1.0"
globals "^11.1.0"
"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9":
version "7.18.10"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6"
integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==
"@babel/types@^7.18.10", "@babel/types@^7.18.13", "@babel/types@^7.18.6", "@babel/types@^7.18.9":
version "7.18.13"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.13.tgz#30aeb9e514f4100f7c1cb6e5ba472b30e48f519a"
integrity sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==
dependencies:
"@babel/helper-string-parser" "^7.18.10"
"@babel/helper-validator-identifier" "^7.18.6"
@ -305,14 +305,14 @@
dependencies:
"@jridgewell/trace-mapping" "0.3.9"
"@eslint/eslintrc@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f"
integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==
"@eslint/eslintrc@^1.3.1":
version "1.3.1"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.1.tgz#de0807bfeffc37b964a7d0400e0c348ce5a2543d"
integrity sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^9.3.2"
espree "^9.4.0"
globals "^13.15.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
@ -334,6 +334,11 @@
resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d"
integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==
"@humanwhocodes/module-importer@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
"@humanwhocodes/object-schema@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
@ -592,9 +597,9 @@
"@types/ms" "*"
"@types/jasmine@^4.0.3":
version "4.0.3"
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-4.0.3.tgz#097ce710d70eb7f3662e96c1f75824dd22c27d5c"
integrity sha512-Opp1LvvEuZdk8fSSvchK2mZwhVrsNT0JgJE9Di6MjnaIpmEXM8TLCPPrVtNTYh8+5MPdY8j9bAHMu2SSfwpZJg==
version "4.3.0"
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-4.3.0.tgz#1dfdfb226820911addb1b5a9031422be72c53aac"
integrity sha512-u1jWakf8CWvLfSEZyxmzkgBzOEvXH/szpT0e6G8BTkx5Eu0BhDn7sbc5dz0JBN/6Wwm9rBe+JAsk9tJRyH9ZkA==
"@types/json-schema@^7.0.9":
version "7.0.11"
@ -612,18 +617,18 @@
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
"@types/node@^18.6.4":
version "18.7.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.4.tgz#95baa50846ae112a7376869d49fec23b2506c69d"
integrity sha512-RzRcw8c0B8LzryWOR4Wj7YOTFXvdYKwvrb6xQQyuDfnlTxwYXGCV5RZ/TEbq5L5kn+w3rliHAUyRcG1RtbmTFg==
version "18.7.13"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.13.tgz#23e6c5168333480d454243378b69e861ab5c011a"
integrity sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==
"@typescript-eslint/eslint-plugin@^5.0.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.0.tgz#059798888720ec52ffa96c5f868e31a8f70fa3ec"
integrity sha512-jHvZNSW2WZ31OPJ3enhLrEKvAZNyAFWZ6rx9tUwaessTc4sx9KmgMNhVcqVAl1ETnT5rU5fpXTLmY9YvC1DCNg==
version "5.35.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.35.1.tgz#0d822bfea7469904dfc1bb8f13cabd362b967c93"
integrity sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg==
dependencies:
"@typescript-eslint/scope-manager" "5.33.0"
"@typescript-eslint/type-utils" "5.33.0"
"@typescript-eslint/utils" "5.33.0"
"@typescript-eslint/scope-manager" "5.35.1"
"@typescript-eslint/type-utils" "5.35.1"
"@typescript-eslint/utils" "5.35.1"
debug "^4.3.4"
functional-red-black-tree "^1.0.1"
ignore "^5.2.0"
@ -632,68 +637,68 @@
tsutils "^3.21.0"
"@typescript-eslint/parser@^5.0.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.33.0.tgz#26ec3235b74f0667414613727cb98f9b69dc5383"
integrity sha512-cgM5cJrWmrDV2KpvlcSkelTBASAs1mgqq+IUGKJvFxWrapHpaRy5EXPQz9YaKF3nZ8KY18ILTiVpUtbIac86/w==
version "5.35.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.35.1.tgz#bf2ee2ebeaa0a0567213748243fb4eec2857f04f"
integrity sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==
dependencies:
"@typescript-eslint/scope-manager" "5.33.0"
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/typescript-estree" "5.33.0"
"@typescript-eslint/scope-manager" "5.35.1"
"@typescript-eslint/types" "5.35.1"
"@typescript-eslint/typescript-estree" "5.35.1"
debug "^4.3.4"
"@typescript-eslint/scope-manager@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.33.0.tgz#509d7fa540a2c58f66bdcfcf278a3fa79002e18d"
integrity sha512-/Jta8yMNpXYpRDl8EwF/M8It2A9sFJTubDo0ATZefGXmOqlaBffEw0ZbkbQ7TNDK6q55NPHFshGBPAZvZkE8Pw==
"@typescript-eslint/scope-manager@5.35.1":
version "5.35.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.35.1.tgz#ccb69d54b7fd0f2d0226a11a75a8f311f525ff9e"
integrity sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==
dependencies:
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/visitor-keys" "5.33.0"
"@typescript-eslint/types" "5.35.1"
"@typescript-eslint/visitor-keys" "5.35.1"
"@typescript-eslint/type-utils@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.33.0.tgz#92ad1fba973c078d23767ce2d8d5a601baaa9338"
integrity sha512-2zB8uEn7hEH2pBeyk3NpzX1p3lF9dKrEbnXq1F7YkpZ6hlyqb2yZujqgRGqXgRBTHWIUG3NGx/WeZk224UKlIA==
"@typescript-eslint/type-utils@5.35.1":
version "5.35.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.35.1.tgz#d50903b56758c5c8fc3be52b3be40569f27f9c4a"
integrity sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw==
dependencies:
"@typescript-eslint/utils" "5.33.0"
"@typescript-eslint/utils" "5.35.1"
debug "^4.3.4"
tsutils "^3.21.0"
"@typescript-eslint/types@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.33.0.tgz#d41c584831805554b063791338b0220b613a275b"
integrity sha512-nIMt96JngB4MYFYXpZ/3ZNU4GWPNdBbcB5w2rDOCpXOVUkhtNlG2mmm8uXhubhidRZdwMaMBap7Uk8SZMU/ppw==
"@typescript-eslint/types@5.35.1":
version "5.35.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.35.1.tgz#af355fe52a0cc88301e889bc4ada72f279b63d61"
integrity sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==
"@typescript-eslint/typescript-estree@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.0.tgz#02d9c9ade6f4897c09e3508c27de53ad6bfa54cf"
integrity sha512-tqq3MRLlggkJKJUrzM6wltk8NckKyyorCSGMq4eVkyL5sDYzJJcMgZATqmF8fLdsWrW7OjjIZ1m9v81vKcaqwQ==
"@typescript-eslint/typescript-estree@5.35.1":
version "5.35.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.35.1.tgz#db878a39a0dbdc9bb133f11cdad451770bfba211"
integrity sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==
dependencies:
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/visitor-keys" "5.33.0"
"@typescript-eslint/types" "5.35.1"
"@typescript-eslint/visitor-keys" "5.35.1"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.33.0.tgz#46797461ce3146e21c095d79518cc0f8ec574038"
integrity sha512-JxOAnXt9oZjXLIiXb5ZIcZXiwVHCkqZgof0O8KPgz7C7y0HS42gi75PdPlqh1Tf109M0fyUw45Ao6JLo7S5AHw==
"@typescript-eslint/utils@5.35.1":
version "5.35.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.35.1.tgz#ae1399afbfd6aa7d0ed1b7d941e9758d950250eb"
integrity sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==
dependencies:
"@types/json-schema" "^7.0.9"
"@typescript-eslint/scope-manager" "5.33.0"
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/typescript-estree" "5.33.0"
"@typescript-eslint/scope-manager" "5.35.1"
"@typescript-eslint/types" "5.35.1"
"@typescript-eslint/typescript-estree" "5.35.1"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
"@typescript-eslint/visitor-keys@5.33.0":
version "5.33.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.0.tgz#fbcbb074e460c11046e067bc3384b5d66b555484"
integrity sha512-/XsqCzD4t+Y9p5wd9HZiptuGKBlaZO5showwqODii5C0nZawxWLF+Q6k5wYHBrQv96h6GYKyqqMHCSTqta8Kiw==
"@typescript-eslint/visitor-keys@5.35.1":
version "5.35.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.35.1.tgz#285e9e34aed7c876f16ff646a3984010035898e6"
integrity sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==
dependencies:
"@typescript-eslint/types" "5.33.0"
"@typescript-eslint/types" "5.35.1"
eslint-visitor-keys "^3.3.0"
acorn-jsx@^5.3.2:
@ -939,9 +944,9 @@ camelcase@^5.0.0, camelcase@^5.3.1:
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
caniuse-lite@^1.0.30001370:
version "1.0.30001376"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001376.tgz#af2450833e5a06873fbb030a9556ca9461a2736d"
integrity sha512-I27WhtOQ3X3v3it9gNs/oTpoE5KpwmqKR5oKPA8M0G7uMXh9Ty81Q904HpKUrM30ei7zfcL5jE7AXefgbOfMig==
version "1.0.30001383"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001383.tgz#aecf317ccd940690725ae3ae4f28293c5fb8050e"
integrity sha512-swMpEoTp5vDoGBZsYZX7L7nXHe6dsHxi9o6/LKf/f0LukVtnrxly5GVb/fWdCDTqi/yw6Km6tiJ0pmBacm0gbg==
chalk@^2.0.0:
version "2.4.2"
@ -1166,9 +1171,9 @@ eastasianwidth@^0.2.0:
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
electron-to-chromium@^1.4.202:
version "1.4.219"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.219.tgz#a7a672304b6aa4f376918d3f63a47f2c3906009a"
integrity sha512-zoQJsXOUw0ZA0YxbjkmzBumAJRtr6je5JySuL/bAoFs0DuLiLJ+5FzRF7/ZayihxR2QcewlRZVm5QZdUhwjOgA==
version "1.4.233"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.233.tgz#aa142e45468bda111b88abc9cc59d573b75d6a60"
integrity sha512-ejwIKXTg1wqbmkcRJh9Ur3hFGHFDZDw1POzdsVrB2WZjgRuRMHIQQKNpe64N/qh3ZtH2otEoRoS+s6arAAuAAw==
emoji-regex@^8.0.0:
version "8.0.0"
@ -1363,13 +1368,14 @@ eslint-visitor-keys@^3.3.0:
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
eslint@^8.21.0:
version "8.22.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48"
integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==
version "8.23.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.0.tgz#a184918d288820179c6041bb3ddcc99ce6eea040"
integrity sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==
dependencies:
"@eslint/eslintrc" "^1.3.0"
"@eslint/eslintrc" "^1.3.1"
"@humanwhocodes/config-array" "^0.10.4"
"@humanwhocodes/gitignore-to-minimatch" "^1.0.2"
"@humanwhocodes/module-importer" "^1.0.1"
ajv "^6.10.0"
chalk "^4.0.0"
cross-spawn "^7.0.2"
@ -1379,7 +1385,7 @@ eslint@^8.21.0:
eslint-scope "^7.1.1"
eslint-utils "^3.0.0"
eslint-visitor-keys "^3.3.0"
espree "^9.3.3"
espree "^9.4.0"
esquery "^1.4.0"
esutils "^2.0.2"
fast-deep-equal "^3.1.3"
@ -1405,12 +1411,11 @@ eslint@^8.21.0:
strip-ansi "^6.0.1"
strip-json-comments "^3.1.0"
text-table "^0.2.0"
v8-compile-cache "^2.0.3"
espree@^9.3.2, espree@^9.3.3:
version "9.3.3"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d"
integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==
espree@^9.4.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a"
integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==
dependencies:
acorn "^8.8.0"
acorn-jsx "^5.3.2"
@ -1568,9 +1573,9 @@ flat-cache@^3.0.4:
rimraf "^3.0.2"
flatted@^3.1.0, flatted@^3.2.5:
version "3.2.6"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2"
integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==
version "3.2.7"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
foreground-child@^2.0.0:
version "2.0.0"
@ -1875,9 +1880,9 @@ internal-slot@^1.0.3:
side-channel "^1.0.4"
ioredis@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.2.2.tgz#212467e04f6779b4e0e800cece7bb7d3d7b546d2"
integrity sha512-wryKc1ur8PcCmNwfcGkw5evouzpbDXxxkMkzPK8wl4xQfQf7lHe11Jotell5ikMVAtikXJEu/OJVaoV51BggRQ==
version "5.2.3"
resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.2.3.tgz#d5b37eb13e643241660d6cee4eeb41a026cda8c0"
integrity sha512-gQNcMF23/NpvjCaa1b5YycUyQJ9rBNH2xP94LWinNpodMWVUPP5Ai/xXANn/SM7gfIvI62B5CCvZxhg5pOgyMw==
dependencies:
"@ioredis/commands" "^1.1.1"
cluster-key-slot "^1.1.0"
@ -2417,9 +2422,9 @@ object-keys@^1.1.1:
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
object.assign@^4.1.2:
version "4.1.3"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.3.tgz#d36b7700ddf0019abb6b1df1bb13f6445f79051f"
integrity sha512-ZFJnX3zltyjcYJL0RoCJuzb+11zWGyaDbjgxZbdV7rFEcHQuYxrZqhow67aA7xpes6LhojyFDaBKAFfogQrikA==
version "4.1.4"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f"
integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.4"
@ -3092,9 +3097,9 @@ typedarray-to-buffer@^3.1.5:
is-typedarray "^1.0.0"
typescript@^4.1.2:
version "4.7.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
version "4.8.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790"
integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==
unbox-primitive@^1.0.2:
version "1.0.2"
@ -3146,11 +3151,6 @@ v8-compile-cache-lib@^3.0.1:
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
v8-compile-cache@^2.0.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
wcwidth@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"