changes access permissions structure to be more typescript-friendly

This commit is contained in:
James
2020-11-24 12:53:09 -05:00
parent 777a2292dc
commit cfdacea210
21 changed files with 119 additions and 125 deletions

View File

@@ -32,7 +32,7 @@ module.exports = {
2,
{
ignore: [
'payload/unsanitizedConfig',
'payload/config',
],
},
],

View File

@@ -5,6 +5,7 @@
"license": "ISC",
"author": "Payload CMS LLC",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts",
"sideEffects": false,
"bin": {
"payload": "./dist/src/bin/index.js"
@@ -94,7 +95,7 @@
"passport-local-mongoose": "^6.0.1",
"path-browserify": "^1.0.1",
"pino": "^6.4.1",
"pino-pretty": "^4.1.0",
"pino-pretty": "^4.3.0",
"pluralize": "^8.0.0",
"postcss-loader": "^4.1.0",
"postcss-preset-env": "^6.7.0",

View File

@@ -121,7 +121,7 @@ const Routes = () => {
path={`${match.url}/collections/${collection.slug}`}
exact
render={(routeProps) => {
if (permissions?.[collection.slug]?.read?.permission) {
if (permissions?.collections?.[collection.slug]?.read?.permission) {
return (
<List
{...routeProps}
@@ -141,7 +141,7 @@ const Routes = () => {
path={`${match.url}/collections/${collection.slug}/create`}
exact
render={(routeProps) => {
if (permissions?.[collection.slug]?.create?.permission) {
if (permissions?.collections?.[collection.slug]?.create?.permission) {
return (
<Edit
{...routeProps}
@@ -161,7 +161,7 @@ const Routes = () => {
path={`${match.url}/collections/${collection.slug}/:id`}
exact
render={(routeProps) => {
if (permissions?.[collection.slug]?.read?.permission) {
if (permissions?.collections?.[collection.slug]?.read?.permission) {
return (
<Edit
isEditing
@@ -182,7 +182,7 @@ const Routes = () => {
path={`${match.url}/globals/${global.slug}`}
exact
render={(routeProps) => {
if (permissions?.[global.slug]?.read?.permission) {
if (permissions?.globals?.[global.slug]?.read?.permission) {
return (
<EditGlobal
{...routeProps}

View File

@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react';
import { NavLink, Link, useHistory } from 'react-router-dom';
import { useConfig } from '@payloadcms/config-provider';
import { useAuth } from '@payloadcms/config-provider';
import { useConfig, useAuth } from '@payloadcms/config-provider';
import RenderCustomComponent from '../../utilities/RenderCustomComponent';
import Chevron from '../../icons/Chevron';
import LogOut from '../../icons/LogOut';
@@ -65,7 +65,7 @@ const DefaultNav = () => {
{collections && collections.map((collection, i) => {
const href = `${admin}/collections/${collection.slug}`;
if (permissions?.[collection.slug]?.read.permission) {
if (permissions?.collections?.[collection.slug]?.read.permission) {
return (
<NavLink
activeClassName="active"
@@ -88,7 +88,7 @@ const DefaultNav = () => {
{globals.map((global, i) => {
const href = `${admin}/globals/${global.slug}`;
if (permissions?.[global.slug].read.permission) {
if (permissions?.globals?.[global.slug].read.permission) {
return (
<NavLink
activeClassName="active"

View File

@@ -7,7 +7,7 @@ import Select from '../../../../../Select';
const createOptions = (collections, permissions) => collections.reduce((options, collection) => {
if (permissions[collection.slug]?.read?.permission && collection?.admin?.enableRichTextRelationship) {
if (permissions?.collections?.[collection.slug]?.read?.permission && collection?.admin?.enableRichTextRelationship) {
return [
...options,
{

View File

@@ -1,8 +1,8 @@
import React, { useState, useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { useConfig } from '@payloadcms/config-provider';
import { useConfig, useAuth } from '@payloadcms/config-provider';
import { useStepNav } from '../../elements/StepNav';
import { useAuth } from '@payloadcms/config-provider';
import usePayloadAPI from '../../../hooks/usePayloadAPI';
import { useLocale } from '../../utilities/Locale';
import DefaultAccount from './Default';
@@ -31,7 +31,7 @@ const AccountView = () => {
const { fields } = collection;
const collectionPermissions = permissions?.[user?.collection];
const collectionPermissions = permissions?.collections?.[user?.collection];
const [{ data, isLoading }] = usePayloadAPI(
`${serverURL}${api}/${collection?.slug}/${user?.id}?depth=0`,

View File

@@ -33,7 +33,7 @@ const Dashboard = (props) => {
<h3 className={`${baseClass}__label`}>Collections</h3>
<ul className={`${baseClass}__card-list`}>
{collections.map((collection) => {
const hasCreatePermission = permissions?.[collection.slug]?.create?.permission;
const hasCreatePermission = permissions?.collections?.[collection.slug]?.create?.permission;
return (
<li key={collection.slug}>

View File

@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
import { useConfig } from '@payloadcms/config-provider';
import { useAuth } from '@payloadcms/config-provider';
import { useConfig, useAuth } from '@payloadcms/config-provider';
import { useStepNav } from '../../elements/StepNav';
import RenderCustomComponent from '../../utilities/RenderCustomComponent';
import DefaultDashboard from './Default';
@@ -22,7 +22,7 @@ const Dashboard = () => {
useEffect(() => {
setFilteredGlobals(
globals.filter((global) => permissions?.[global.slug]?.read?.permission),
globals.filter((global) => permissions?.globals?.[global.slug]?.read?.permission),
);
}, [permissions, globals]);
@@ -36,7 +36,7 @@ const Dashboard = () => {
CustomComponent={CustomDashboard}
componentProps={{
globals: filteredGlobals,
collections: collections.filter((collection) => permissions?.[collection.slug]?.read?.permission),
collections: collections.filter((collection) => permissions?.collections?.[collection.slug]?.read?.permission),
permissions,
}}
/>

View File

@@ -1,10 +1,10 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useHistory, useLocation } from 'react-router-dom';
import { useConfig } from '@payloadcms/config-provider';
import { useConfig, useAuth } from '@payloadcms/config-provider';
import { useStepNav } from '../../elements/StepNav';
import usePayloadAPI from '../../../hooks/usePayloadAPI';
import { useAuth } from '@payloadcms/config-provider';
import { useLocale } from '../../utilities/Locale';
import RenderCustomComponent from '../../utilities/RenderCustomComponent';
@@ -77,7 +77,7 @@ const GlobalView = (props) => {
awaitInitialState();
}, [dataToRender, fields]);
const globalPermissions = permissions?.[slug];
const globalPermissions = permissions?.globals?.[slug];
return (
<NegativeFieldGutterProvider allow>

View File

@@ -1,10 +1,10 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Redirect, useRouteMatch, useHistory, useLocation } from 'react-router-dom';
import { useConfig } from '@payloadcms/config-provider';
import { useConfig, useAuth } from '@payloadcms/config-provider';
import { useStepNav } from '../../../elements/StepNav';
import usePayloadAPI from '../../../../hooks/usePayloadAPI';
import { useAuth } from '@payloadcms/config-provider';
import RenderCustomComponent from '../../../utilities/RenderCustomComponent';
import DefaultEdit from './Default';
@@ -91,7 +91,7 @@ const EditView = (props) => {
);
}
const collectionPermissions = permissions?.[slug];
const collectionPermissions = permissions?.collections?.[slug];
const apiURL = `${serverURL}${api}/${slug}/${id}`;
const action = `${serverURL}${api}/${slug}${isEditing ? `/${id}` : ''}?locale=${locale}&depth=0`;

View File

@@ -2,8 +2,8 @@ import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import queryString from 'qs';
import { useLocation } from 'react-router-dom';
import { useConfig } from '@payloadcms/config-provider';
import { useAuth } from '@payloadcms/config-provider';
import { useConfig, useAuth } from '@payloadcms/config-provider';
import usePayloadAPI from '../../../../hooks/usePayloadAPI';
import DefaultList from './Default';
import RenderCustomComponent from '../../../utilities/RenderCustomComponent';
@@ -37,7 +37,7 @@ const ListView = (props) => {
const [columns, setColumns] = useState([]);
const [sort, setSort] = useState(null);
const collectionPermissions = permissions?.[slug];
const collectionPermissions = permissions?.collections?.[slug];
const hasCreatePermission = collectionPermissions?.create?.permission;
const { page } = queryString.parse(location.search, { ignoreQueryPrefix: true });

View File

@@ -1,3 +1,6 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - need to do this because this file doesn't actually exist
import config from 'payload/config';
import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
@@ -6,7 +9,6 @@ import { WindowInfoProvider } from '@faceless-ui/window-info';
import { ModalProvider, ModalContainer } from '@faceless-ui/modal';
import { ToastContainer, Slide } from 'react-toastify';
import { ConfigProvider, AuthProvider } from '@payloadcms/config-provider';
import unsanitizedConfig from 'payload/unsanitizedConfig';
import { SearchParamsProvider } from './components/utilities/SearchParams';
import { LocaleProvider } from './components/utilities/Locale';
import Routes from './components/Routes';
@@ -16,7 +18,7 @@ import './scss/app.scss';
const Index = () => (
<React.Fragment>
<ConfigProvider config={unsanitizedConfig}>
<ConfigProvider config={config}>
<WindowInfoProvider breakpoints={{
xs: parseInt(getCSSVariable('breakpoint-xs-width').replace('px', ''), 10),
s: parseInt(getCSSVariable('breakpoint-s-width').replace('px', ''), 10),

View File

@@ -67,18 +67,20 @@ async function accessOperation(args) {
});
};
const executeEntityPolicies = (entity, operations) => {
results[entity.slug] = {
const executeEntityPolicies = (entity, operations, type) => {
if (!results[type]) results[type] = {};
results[type][entity.slug] = {
fields: {},
};
operations.forEach((operation) => {
executeFieldPolicies(results[entity.slug].fields, entity.fields, operation);
executeFieldPolicies(results[type][entity.slug].fields, entity.fields, operation);
if (typeof entity.access[operation] === 'function') {
promises.push(createAccessPromise(results[entity.slug], entity.access[operation], operation));
promises.push(createAccessPromise(results[type][entity.slug], entity.access[operation], operation));
} else {
results[entity.slug][operation] = {
results[type][entity.slug][operation] = {
permission: isLoggedIn,
};
}
@@ -87,17 +89,17 @@ async function accessOperation(args) {
if (userCollectionConfig) {
results.canAccessAdmin = userCollectionConfig.access.admin ? userCollectionConfig.access.admin(args) : isLoggedIn;
if (results.canAccessAdmin) results.license = config.license;
if (results.canAccessAdmin) results.license = this.license;
} else {
results.canAccessAdmin = false;
}
config.collections.forEach((collection) => {
executeEntityPolicies(collection, allOperations);
executeEntityPolicies(collection, allOperations, 'collection');
});
config.globals.forEach((global) => {
executeEntityPolicies(global, ['read', 'update']);
executeEntityPolicies(global, ['read', 'update'], 'global');
});
await Promise.all(promises);

View File

@@ -3,31 +3,51 @@ export type Permission = {
where?: Record<string, unknown>
}
export type Permissions = {
[key: string]: boolean | {
create: Permission
read: Permission
update: Permission
delete: Permission
fields: {
[field: string]: {
create: {
permission: boolean
}
read: {
permission: boolean
}
update: {
permission: boolean
}
delete: {
permission: boolean
}
export type CollectionPermission = {
create: Permission
read: Permission
update: Permission
delete: Permission
fields: {
[field: string]: {
create: {
permission: boolean
}
read: {
permission: boolean
}
update: {
permission: boolean
}
delete: {
permission: boolean
}
}
}
}
export type GlobalPermission = {
read: Permission
update: Permission
fields: {
[field: string]: {
read: {
permission: boolean
}
update: {
permission: boolean
}
}
}
}
export type Permissions = {
canAccessAdmin: boolean
license?: string
collections: CollectionPermission[]
globals?: GlobalPermission[]
}
export type User = {
id: string
email: string

View File

@@ -66,7 +66,6 @@ const sanitizeConfig = (config: Config): Config => {
sanitizedConfig.components = { ...(config.components || {}) };
sanitizedConfig.hooks = { ...(config.hooks || {}) };
sanitizedConfig.admin = { ...(config.admin || {}) };
return sanitizedConfig as DeepRequired<Config>;
};

View File

@@ -3,7 +3,8 @@ import { Response, NextFunction } from 'express';
import formatErrorResponse from '../responses/formatError';
import { PayloadRequest } from '../types/payloadRequest';
const errorHandler = (config, logger) => async (err, req: PayloadRequest, res: Response): Promise<void> => {
// NextFunction must be passed for Express to use this middleware as error handler
const errorHandler = (config, logger) => async (err, req: PayloadRequest, res: Response, next: NextFunction): Promise<void> => {
const data = formatErrorResponse(err);
let response;
let status = err.status || httpStatus.INTERNAL_SERVER_ERROR;

View File

@@ -318,4 +318,7 @@ export class Payload {
}
}
module.exports = new Payload();
const payload = new Payload();
export default payload;
module.exports = payload;

View File

@@ -78,7 +78,7 @@ export default (config: Config): Configuration => {
},
modules: ['node_modules', path.resolve(__dirname, '../../node_modules')],
alias: {
'payload/unsanitizedConfig': config.paths.config,
'payload/config': config.paths.config,
'@payloadcms/payload$': mockModulePath,
},
extensions: ['.ts', '.tsx', '.js', '.json'],

View File

@@ -103,7 +103,7 @@ export default (config: Config): Configuration => {
},
modules: ['node_modules', path.resolve(__dirname, '../../node_modules')],
alias: {
'payload/unsanitizedConfig': config.paths.config,
'payload/config': config.paths.config,
'@payloadcms/payload$': mockModulePath,
},
},

View File

@@ -1,60 +1,27 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
"target": "esnext",
"module": "commonjs",
"allowJs": true, /* Allow javascript files to be compiled. */
"checkJs": false, /* Report errors in .js files. */
"jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
"declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
/* Concatenate and emit output to single file. */
"outDir": "./dist", /* Redirect output structure to the directory. */
"rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
/* Do not emit comments to output. */
"noEmit": false, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": false, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"baseUrl": "",
"paths": {
"payload/config": [
"src/admin/types/config" // Webpack alias to user config
],
},
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
"resolveJsonModule": true,
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
"inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
},

View File

@@ -2150,9 +2150,9 @@
loglevel "^1.6.2"
"@types/webpack-env@^1.15.3":
version "1.15.3"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.3.tgz#fb602cd4c2f0b7c0fb857e922075fdf677d25d84"
integrity sha512-5oiXqR7kwDGZ6+gmzIO2lTC+QsriNuQXZDWNYRV3l2XRN/zmPgnC21DLSx2D05zvD8vnXW6qUg7JnXZ4I6qLVQ==
version "1.16.0"
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.0.tgz#8c0a9435dfa7b3b1be76562f3070efb3f92637b4"
integrity sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw==
"@types/webpack-hot-middleware@^2.25.3":
version "2.25.3"
@@ -3427,9 +3427,9 @@ caniuse-api@^3.0.0:
lodash.uniq "^4.5.0"
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001157:
version "1.0.30001159"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001159.tgz#bebde28f893fa9594dadcaa7d6b8e2aa0299df20"
integrity sha512-w9Ph56jOsS8RL20K9cLND3u/+5WASWdhC/PPrf+V3/HsM3uHOavWOR1Xzakbv4Puo/srmPHudkmCRWM7Aq+/UA==
version "1.0.30001161"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001161.tgz#64f7ffe79ee780b8c92843ff34feb36cea4651e0"
integrity sha512-JharrCDxOqPLBULF9/SPa6yMcBRTjZARJ6sc3cuKrPfyIk64JN6kuMINWqA99Xc8uElMFcROliwtz0n9pYej+g==
capture-exit@^2.0.0:
version "2.0.0"
@@ -4646,9 +4646,9 @@ ejs@^2.6.1:
integrity sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==
electron-to-chromium@^1.3.591:
version "1.3.604"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.604.tgz#285da30e38a71e2b9d28ce3a792ec60235c63b7c"
integrity sha512-Mk5ODhvz+ZaQpVFXbu51wGW94P3CnkJIDkEQGxXMl6Ix6R0PG4IFWz83WbqFEZjN1UksoTsmmzKY5SmUrEvNJQ==
version "1.3.606"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.606.tgz#6ef2655d9a7c1b447dfdd6344657d00461a65e26"
integrity sha512-+/2yPHwtNf6NWKpaYt0KoqdSZ6Qddt6nDfH/pnhcrHq9hSb23e5LFy06Mlf0vF2ykXvj7avJ597psqcbKnG5YQ==
emittery@^0.7.1:
version "0.7.2"
@@ -4850,11 +4850,12 @@ eslint-plugin-import@^2.20.0:
tsconfig-paths "^3.9.0"
eslint-plugin-jest-dom@^3.0.1:
version "3.2.4"
resolved "https://registry.yarnpkg.com/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-3.2.4.tgz#78e95c48755240a4d1e9d6c3bdcd87ea4af242b9"
integrity sha512-CRR5rMMJgLKjxHHuio/oy4tt5gnUohgGNMzLM0p0THoyRYewzV/PE+8qUUHSyTO+iexCvgnHukdRfckdyi+5tg==
version "3.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-3.3.0.tgz#5be14f8c303b7e8551b426bc7ac8a152d01736ae"
integrity sha512-/7LqlMPiZh4SHy8YXSHilcx/zy7m5Fb7rl4AlzjIY8+amsGP2nZq9WIbMv0JYYVeq20p5+44GmWO6dCZcdLj4A==
dependencies:
"@babel/runtime" "^7.9.6"
"@testing-library/dom" "^7.28.1"
requireindex "^1.2.0"
eslint-plugin-jest@^23.16.0:
@@ -6479,9 +6480,9 @@ is-hexadecimal@^1.0.0:
integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
is-hotkey@^0.1.6:
version "0.1.7"
resolved "https://registry.yarnpkg.com/is-hotkey/-/is-hotkey-0.1.7.tgz#15b89a80c71df0a7367bafa8629a187196586522"
integrity sha512-fOzQF4+oex9Alhn4vDxzukeO5kwpn825U8CjACFD5MtPs52/0RnkYNYmhSDD6sPfRngCr/c6+VGyF3Wc7Jv+iw==
version "0.1.8"
resolved "https://registry.yarnpkg.com/is-hotkey/-/is-hotkey-0.1.8.tgz#6b1f4b2d0e5639934e20c05ed24d623a21d36d25"
integrity sha512-qs3NZ1INIS+H+yeo7cD9pDfwYV/jqRh1JG9S9zYrNudkoUQg7OL7ziXqRKu+InFjUIDoP2o6HIkLYMh1pcWgyQ==
is-installed-globally@^0.1.0:
version "0.1.0"
@@ -8821,7 +8822,7 @@ pinkie@^2.0.0:
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
pino-pretty@^4.1.0:
pino-pretty@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-4.3.0.tgz#18695606fd4f1e21cd1585d18999cd84d429e1d8"
integrity sha512-uEc9SUCCGVEs0goZvyznKXBHtI1PNjGgqHviJHxOCEFEWZN6Z/IQKv5pO9gSdm/b+WfX+/dfheWhtZUyScqjlQ==
@@ -11738,12 +11739,11 @@ ts-easing@^0.2.0:
resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec"
integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==
<<<<<<< HEAD
ts-essentials@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.1.tgz#d205508cae0cdadfb73c89503140cf2228389e2d"
integrity sha512-8lwh3QJtIc1UWhkQtr9XuksXu3O0YQdEE5g79guDfhCaU1FWTDIEDZ1ZSx4HTHUmlJZ8L812j3BZQ4a0aOUkSA==
=======
tsc-silent@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/tsc-silent/-/tsc-silent-1.2.1.tgz#c219789b7b1ab8e475fe3069d061d5ab49167d3f"
@@ -11751,7 +11751,6 @@ tsc-silent@^1.2.1:
dependencies:
"@types/node" "10.12.7"
yargs "12 - 15"
>>>>>>> 062771e0a720fc1684a4754e42b14b95c9cc2c73
tsconfig-paths@^3.9.0:
version "3.9.0"