1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Merge remote-tracking branch 'origin/master' into load_resources_per_namespaces

# Conflicts:
#	src/renderer/components/item-object-list/item-list-layout.tsx
This commit is contained in:
Roman 2021-01-13 18:24:58 +02:00
commit ff89638787
18 changed files with 203 additions and 139 deletions

View File

@ -57,7 +57,10 @@ jobs:
displayName: Run tests
- script: make test-extensions
displayName: Run In-tree Extension tests
- script: make integration-win
- bash: |
rm -rf extensions/telemetry
make integration-win
git checkout extensions/telemetry
displayName: Run integration tests
- script: make build
condition: "and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))"
@ -98,7 +101,10 @@ jobs:
displayName: Run tests
- script: make test-extensions
displayName: Run In-tree Extension tests
- script: make integration-mac
- bash: |
rm -rf extensions/telemetry
make integration-mac
git checkout extensions/telemetry
displayName: Run integration tests
- script: make test-extensions
displayName: Run In-tree Extension tests
@ -152,7 +158,10 @@ jobs:
# Although the kube and minikube config files are in placed $HOME they are owned by root
sudo chown -R $USER $HOME/.kube $HOME/.minikube
displayName: Install integration test dependencies
- script: xvfb-run --auto-servernum --server-args='-screen 0, 1600x900x24' make integration-linux
- bash: |
rm -rf extensions/telemetry
xvfb-run --auto-servernum --server-args='-screen 0, 1600x900x24' make integration-linux
git checkout extensions/telemetry
displayName: Run integration tests
- bash: |
sudo chown root:root /

1
.gitignore vendored
View File

@ -17,3 +17,4 @@ types/extension-renderer-api.d.ts
extensions/*/dist
docs/extensions/api
site/
.vscode/

View File

@ -105,34 +105,18 @@ docs:
.PHONY: clean-extensions
clean-extensions:
ifeq "$(DETECTED_OS)" "Windows"
$(foreach dir, $(wildcard $(EXTENSIONS_DIR)/*), if exist $(dir)\dist del /s /q $(dir)\dist)
$(foreach dir, $(wildcard $(EXTENSIONS_DIR)/*), if exist $(dir)\node_modules del /s /q $(dir)\node_modules)
else
$(foreach dir, $(wildcard $(EXTENSIONS_DIR)/*), rm -rf $(dir)/dist)
$(foreach dir, $(wildcard $(EXTENSIONS_DIR)/*), rm -rf $(dir)/node_modules)
endif
.PHONY: clean-npm
clean-npm:
ifeq "$(DETECTED_OS)" "Windows"
if exist src\extensions\npm\extensions\dist del /s /q src\extensions\npm\extensions\dist
if exist src\extensions\npm\extensions\__mocks__ del /s /q src\extensions\npm\extensions\__mocks__
if exist src\extensions\npm\extensions\node_modules del /s /q src\extensions\npm\extensions\node_modules
else
rm -rf src/extensions/npm/extensions/dist
rm -rf src/extensions/npm/extensions/__mocks__
rm -rf src/extensions/npm/extensions/node_modules
endif
.PHONY: clean
clean: clean-npm clean-extensions
ifeq "$(DETECTED_OS)" "Windows"
if exist binaries\client del /s /q binaries\client
if exist dist del /s /q dist\*.*
if exist static\build del /s /q static\build\*.*
else
rm -rf binaries/client
rm -rf dist/*
rm -rf static/build/*
endif
rm -rf node_modules/

View File

@ -19,6 +19,9 @@ When contributing to this repository, please consider first discussing the chang
* `make dev` - builds and starts the app
* `make clean` - cleanup local environment build artifacts
### Developing on Windows
On Windows we only support [Git Bash](https://gitforwindows.org/) (or similar shell) for running commands.
## Github Workflow

View File

@ -224,7 +224,7 @@
"tar": "^6.0.5",
"tcp-port-used": "^1.0.1",
"tempy": "^0.5.0",
"uuid": "^8.1.0",
"uuid": "^8.3.2",
"win-ca": "^3.2.0",
"winston": "^3.2.1",
"winston-transport-browserconsole": "^1.0.5",
@ -279,18 +279,18 @@
"@types/tempy": "^0.3.0",
"@types/terser-webpack-plugin": "^3.0.0",
"@types/universal-analytics": "^0.4.4",
"@types/uuid": "^8.0.0",
"@types/uuid": "^8.3.0",
"@types/webdriverio": "^4.13.0",
"@types/webpack": "^4.41.17",
"@types/webpack-dev-server": "^3.11.1",
"@types/webpack-env": "^1.15.2",
"@types/webpack-node-externals": "^1.7.1",
"@typescript-eslint/eslint-plugin": "^4.0.0",
"@typescript-eslint/eslint-plugin": "^4.12.0",
"@typescript-eslint/parser": "^4.0.0",
"ace-builds": "^1.4.11",
"ansi_up": "^4.0.4",
"chart.js": "^2.9.3",
"circular-dependency-plugin": "^5.2.0",
"circular-dependency-plugin": "^5.2.2",
"color": "^3.1.2",
"concurrently": "^5.2.0",
"css-element-queries": "^1.2.3",

View File

@ -28,6 +28,7 @@ export interface UserPreferences {
downloadBinariesPath?: string;
kubectlBinariesPath?: string;
openAtLogin?: boolean;
hiddenTableColumns?: Record<string, string[]>
}
export class UserStore extends BaseStore<UserStoreModel> {
@ -54,6 +55,7 @@ export class UserStore extends BaseStore<UserStoreModel> {
downloadMirror: "default",
downloadKubectlBinaries: true, // Download kubectl binaries matching cluster version
openAtLogin: false,
hiddenTableColumns: {},
};
protected async handleOnLoad() {

View File

@ -10,7 +10,7 @@ import { workspaceStore } from "../common/workspace-store";
import { preferencesURL } from "../renderer/components/+preferences/preferences.route";
import { clusterViewURL } from "../renderer/components/cluster-manager/cluster-view.route";
import logger from "./logger";
import { isDevelopment } from "../common/vars";
import { isDevelopment, isWindows } from "../common/vars";
import { exitApp } from "./exit-app";
// note: instance of Tray should be saved somewhere, otherwise it disappears
@ -29,7 +29,7 @@ export function initTray(windowManager: WindowManager) {
try {
const menu = createTrayMenu(windowManager);
buildTray(getTrayIcon(), menu);
buildTray(getTrayIcon(), menu, windowManager);
} catch (err) {
logger.error(`[TRAY]: building failed: ${err}`);
}
@ -42,20 +42,25 @@ export function initTray(windowManager: WindowManager) {
};
}
export function buildTray(icon: string | NativeImage, menu: Menu) {
function buildTray(icon: string | NativeImage, menu: Menu, windowManager: WindowManager) {
if (!tray) {
tray = new Tray(icon);
tray.setToolTip(packageInfo.description);
tray.setIgnoreDoubleClickEvents(true);
}
tray.setImage(icon);
tray.setContextMenu(menu);
tray.setImage(icon);
tray.setContextMenu(menu);
if (isWindows) {
tray.on("click", () => {
windowManager.ensureMainWindow();
});
}
}
return tray;
}
export function createTrayMenu(windowManager: WindowManager): Menu {
function createTrayMenu(windowManager: WindowManager): Menu {
return Menu.buildFromTemplate([
{
label: "About Lens",

View File

@ -78,10 +78,24 @@ export function normalizeMetrics(metrics: IMetrics, frames = 60): IMetrics {
result.forEach(res => {
if (!res.values || !res.values.length) return;
let now = moment().startOf("minute").subtract(1, "minute").unix();
let timestamp = res.values[0][0];
while (timestamp <= now) {
timestamp = moment.unix(timestamp).add(1, "minute").unix();
if (!res.values.find((value) => value[0] === timestamp)) {
res.values.push([timestamp, "0"]);
}
}
while (res.values.length < frames) {
const timestamp = moment.unix(res.values[0][0]).subtract(1, "minute").unix();
res.values.unshift([timestamp, "0"]);
if (!res.values.find((value) => value[0] === timestamp)) {
res.values.unshift([timestamp, "0"]);
}
now = timestamp;
}
});
}

View File

@ -18,7 +18,7 @@ export const resourceApplierApi = {
.post<KubeJsonApiData[]>("/stack", { data: resource })
.then(data => {
const items = data.map(obj => {
const api = apiManager.getApi(obj.metadata.selfLink);
const api = apiManager.getApiByKind(obj.kind, obj.apiVersion);
if (api) {
return new api.objectConstructor(obj);

View File

@ -4,7 +4,7 @@ import React, { Fragment } from "react";
import { observer } from "mobx-react";
import { TabLayout } from "../layout/tab-layout";
import { eventStore } from "./event.store";
import { KubeObjectListLayout, KubeObjectListLayoutProps, getDetailsUrl } from "../kube-object";
import { getDetailsUrl, KubeObjectListLayout, KubeObjectListLayoutProps } from "../kube-object";
import { KubeEvent } from "../../api/endpoints/events.api";
import { Tooltip } from "../tooltip";
import { Link } from "react-router-dom";
@ -65,7 +65,7 @@ export class Events extends React.Component<Props> {
small
material="help_outline"
className="help-icon"
tooltip="Limited to {eventStore.limit}"
tooltip={`Limited to ${eventStore.limit}`}
/>
</>
)

View File

@ -7,6 +7,7 @@ import { IResourceMetricsValue, ResourceMetricsContext } from "../resource-metri
import { observer } from "mobx-react";
import { ChartOptions, ChartPoint } from "chart.js";
import { themeStore } from "../../theme.store";
import { mapValues } from "lodash";
type IContext = IResourceMetricsValue<Node, { metrics: IClusterMetrics }>;
@ -15,26 +16,26 @@ export const NodeCharts = observer(() => {
const id = object.getId();
const { chartCapacityColor } = themeStore.activeTheme.colors;
if (!metrics) return null;
if (isMetricsEmpty(metrics)) return <NoMetrics/>;
if (!metrics) {
return null;
}
const values = Object.values(metrics).map(metric =>
normalizeMetrics(metric).data.result[0].values
);
const [
if (isMetricsEmpty(metrics)) {
return <NoMetrics />;
}
const {
memoryUsage,
memoryRequests,
_memoryLimits, // eslint-disable-line unused-imports/no-unused-vars-ts
memoryCapacity,
cpuUsage,
cpuRequests,
_cpuLimits, // eslint-disable-line unused-imports/no-unused-vars-ts
cpuCapacity,
podUsage,
podCapacity,
fsSize,
fsUsage
] = values;
} = mapValues(metrics, metric => normalizeMetrics(metric).data.result[0].values);
const datasets = [
// CPU

View File

@ -74,6 +74,8 @@ export class Pods extends React.Component<Props> {
<KubeObjectListLayout
className="Pods" store={podsStore}
dependentStores={[volumeClaimStore, eventStore]}
tableId = "workloads_pods"
isConfigurable
sortingCallbacks={{
[sortBy.name]: (pod: Pod) => pod.getName(),
[sortBy.namespace]: (pod: Pod) => pod.getNs(),
@ -94,7 +96,7 @@ export class Pods extends React.Component<Props> {
renderHeaderTitle="Pods"
renderTableHeader={[
{ title: "Name", className: "name", sortBy: sortBy.name },
{ className: "warning" },
{ className: "warning", showWithColumn: "name" },
{ title: "Namespace", className: "namespace", sortBy: sortBy.namespace },
{ title: "Containers", className: "containers", sortBy: sortBy.containers },
{ title: "Restarts", className: "restarts", sortBy: sortBy.restarts },

View File

@ -22,7 +22,7 @@
height: 18px; // Must be equal to lineHeight variable in pod-log-list.tsx
font-family: var(--font-monospace);
font-size: smaller;
white-space: pre;
white-space: nowrap;
&:hover {
background: var(--logRowHoverBackground);

View File

@ -1,4 +1,5 @@
import "./item-list-layout.scss";
import "./table-menu.scss";
import groupBy from "lodash/groupBy";
import React, { ReactNode } from "react";
@ -18,6 +19,11 @@ import { PageFiltersList } from "./page-filters-list";
import { PageFiltersSelect } from "./page-filters-select";
import { NamespaceSelectFilter } from "../+namespaces/namespace-select";
import { themeStore } from "../../theme.store";
import { MenuActions} from "../menu/menu-actions";
import { MenuItem } from "../menu";
import { Checkbox } from "../checkbox";
import { userStore } from "../../../common/user-store";
import logger from "../../../main/logger";
// todo: refactor, split to small re-usable components
@ -32,6 +38,7 @@ interface IHeaderPlaceholders {
}
export interface ItemListLayoutProps<T extends ItemObject = ItemObject> {
tableId?: string;
className: IClassName;
store: ItemStore<T>;
dependentStores?: ItemStore[];
@ -50,6 +57,7 @@ export interface ItemListLayoutProps<T extends ItemObject = ItemObject> {
isReady?: boolean; // show loading indicator while not ready
isSelectable?: boolean; // show checkbox in rows for selecting items
isSearchable?: boolean; // apply search-filter & add search-input
isConfigurable?: boolean;
copyClassNameFromHeadCells?: boolean;
sortingCallbacks?: { [sortBy: string]: TableSortCallback };
tableProps?: Partial<TableProps>; // low-level table configuration
@ -74,6 +82,7 @@ const defaultProps: Partial<ItemListLayoutProps> = {
showHeader: true,
isSearchable: true,
isSelectable: true,
isConfigurable: false,
copyClassNameFromHeadCells: true,
dependentStores: [],
filterItems: [],
@ -92,6 +101,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
private watchDisposers: IReactionDisposer[] = [];
@observable hiddenColumnNames = new Set<string>();
@observable isUnmounting = false;
@observable userSettings: ItemListLayoutUserSettings = {
@ -127,7 +137,10 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
}
@computed get stores() {
const { store, dependentStores, isClusterScoped } = this.props;
const { store, dependentStores, isClusterScoped, tableId } = this.props;
if (this.canBeConfigured) this.hiddenColumnNames = new Set(userStore.preferences?.hiddenTableColumns?.[tableId]);
const stores = new Set([store, ...dependentStores]);
if (!isClusterScoped) {
@ -240,6 +253,42 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
return this.applyFilters(filterItems, allItems);
}
updateColumnFilter(checkboxValue: boolean, columnName: string) {
if (checkboxValue){
this.hiddenColumnNames.delete(columnName);
} else {
this.hiddenColumnNames.add(columnName);
}
if (this.canBeConfigured) {
userStore.preferences.hiddenTableColumns[this.props.tableId] = Array.from(this.hiddenColumnNames);
}
}
columnIsVisible(index: number): boolean {
const {renderTableHeader} = this.props;
if (!this.canBeConfigured) return true;
return !this.hiddenColumnNames.has(renderTableHeader[index].showWithColumn ?? renderTableHeader[index].className);
}
get canBeConfigured(): boolean {
const { isConfigurable, tableId, renderTableHeader } = this.props;
if (!isConfigurable || !tableId) {
return false;
}
if (!renderTableHeader?.every(({ className }) => className)) {
logger.warning("[ItemObjectList]: cannot configure an object list without all headers being identifiable");
return false;
}
return true;
}
@autobind()
getRow(uid: string) {
const {
@ -283,7 +332,7 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
}
}
return <TableCell key={index} {...cellProps} />;
return this.columnIsVisible(index) ? <TableCell key={index} {...cellProps} /> : null;
})
}
{renderItemMenu && (
@ -450,14 +499,18 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
onClick={prevDefault(() => store.toggleSelectionAll(items))}
/>
)}
{renderTableHeader.map((cellProps, index) => <TableCell key={index} {...cellProps} />)}
{renderItemMenu && <TableCell className="menu"/>}
{renderTableHeader.map((cellProps, index) => this.columnIsVisible(index) ? <TableCell key={index} {...cellProps} /> : null)}
{renderItemMenu && <TableCell className="menu">
{this.canBeConfigured && this.renderColumnMenu()}
</TableCell>
}
</TableHead>
)}
{
!virtual && items.map(item => this.getRow(item.getId()))
}
</Table>
)}
<AddRemoveButtons
onRemove={selectedItems.length ? removeItemsDialog : null}
@ -468,6 +521,29 @@ export class ItemListLayout extends React.Component<ItemListLayoutProps> {
);
}
renderColumnMenu() {
const { renderTableHeader} = this.props;
return (
<MenuActions
toolbar = {false}
autoCloseOnSelect = {false}
className={cssNames("KubeObjectMenu")}
>
{renderTableHeader.map((cellProps, index) => (
!cellProps.showWithColumn &&
<MenuItem key={index} className="input">
<Checkbox label = {cellProps.title ?? `<${cellProps.className}>`}
className = "MenuCheckbox"
value ={!this.hiddenColumnNames.has(cellProps.className)}
onChange = {(v) => this.updateColumnFilter(v, cellProps.className)}
/>
</MenuItem>
))}
</MenuActions>
);
}
renderFooter() {
if (this.props.renderFooter) {
return this.props.renderFooter(this);

View File

@ -0,0 +1,4 @@
.MenuCheckbox {
width: 100%;
height: 100%;
}

View File

@ -13,6 +13,7 @@ import isString from "lodash/isString";
export interface MenuActionsProps extends Partial<MenuProps> {
className?: string;
toolbar?: boolean; // display menu as toolbar with icons
autoCloseOnSelect?: boolean;
triggerIcon?: string | IconProps | React.ReactNode;
removeConfirmationMessage?: React.ReactNode | (() => React.ReactNode);
updateAction?(): void;
@ -80,7 +81,7 @@ export class MenuActions extends React.Component<MenuActionsProps> {
render() {
const {
className, toolbar, children, updateAction, removeAction, triggerIcon, removeConfirmationMessage,
className, toolbar, autoCloseOnSelect, children, updateAction, removeAction, triggerIcon, removeConfirmationMessage,
...menuProps
} = this.props;
const menuClassName = cssNames("MenuActions flex", className, {
@ -98,7 +99,7 @@ export class MenuActions extends React.Component<MenuActionsProps> {
className={menuClassName}
usePortal={autoClose}
closeOnScroll={autoClose}
closeOnClickItem={autoClose}
closeOnClickItem={autoCloseOnSelect ?? autoClose }
closeOnClickOutside={autoClose}
{...menuProps}
>

View File

@ -15,6 +15,7 @@ export interface TableCellProps extends React.DOMAttributes<HTMLDivElement> {
isChecked?: boolean; // mark checkbox as checked or not
renderBoolean?: boolean; // show "true" or "false" for all of the children elements are "typeof boolean"
sortBy?: TableSortBy; // column name, must be same as key in sortable object <Table sortable={}/>
showWithColumn?: string // className of another column, if it is not empty the current column is not shown in the filter menu, visibility of this one is the same as a specified column, applicable to headers only
_sorting?: Partial<TableSortParams>; // <Table> sorting state, don't use this prop outside (!)
_sort?(sortBy: TableSortBy): void; // <Table> sort function, don't use this prop outside (!)
_nowrap?: boolean; // indicator, might come from parent <TableHead>, don't use this prop outside (!)
@ -63,7 +64,7 @@ export class TableCell extends React.Component<TableCellProps> {
}
render() {
const { className, checkbox, isChecked, sortBy, _sort, _sorting, _nowrap, children, title, renderBoolean: displayBoolean, ...cellProps } = this.props;
const { className, checkbox, isChecked, sortBy, _sort, _sorting, _nowrap, children, title, renderBoolean: displayBoolean, showWithColumn, ...cellProps } = this.props;
const classNames = cssNames("TableCell", className, {
checkbox,
nowrap: _nowrap,

133
yarn.lock
View File

@ -1710,10 +1710,10 @@
resolved "https://registry.yarnpkg.com/@types/universal-analytics/-/universal-analytics-0.4.4.tgz#496a52b92b599a0112bec7c12414062de6ea8449"
integrity sha512-9g3F0SGxVr4UDd6y07bWtFnkpSSX1Ake7U7AGHgSFrwM6pF53/fV85bfxT2JLWS/3sjLCcyzoYzQlCxpkVo7wA==
"@types/uuid@^8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0"
integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw==
"@types/uuid@^8.3.0":
version "8.3.0"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f"
integrity sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==
"@types/webdriverio@^4.13.0", "@types/webdriverio@^4.8.0":
version "4.13.3"
@ -1792,53 +1792,28 @@
dependencies:
"@types/node" "*"
"@typescript-eslint/eslint-plugin@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.0.0.tgz#99349a501447fed91de18346705c0c65cf603bee"
integrity sha512-5e6q1TR7gS2P+8W2xndCu7gBh3BzmYEo70OyIdsmCmknHha/yNbz2vdevl+tP1uoaMOcrzg4gyrAijuV3DDBHA==
"@typescript-eslint/eslint-plugin@^4.12.0", "@typescript-eslint/eslint-plugin@^4.5.0":
version "4.12.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.12.0.tgz#00d1b23b40b58031e6d7c04a5bc6c1a30a2e834a"
integrity sha512-wHKj6q8s70sO5i39H2g1gtpCXCvjVszzj6FFygneNFyIAxRvNSVz9GML7XpqrB9t7hNutXw+MHnLN/Ih6uyB8Q==
dependencies:
"@typescript-eslint/experimental-utils" "4.0.0"
"@typescript-eslint/scope-manager" "4.0.0"
"@typescript-eslint/experimental-utils" "4.12.0"
"@typescript-eslint/scope-manager" "4.12.0"
debug "^4.1.1"
functional-red-black-tree "^1.0.1"
regexpp "^3.0.0"
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/eslint-plugin@^4.5.0":
version "4.8.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.8.2.tgz#cf9102ec800391caa574f589ffe0623cca1d9308"
integrity sha512-gQ06QLV5l1DtvYtqOyFLXD9PdcILYqlrJj2l+CGDlPtmgLUzc1GpqciJFIRvyfvgLALpnxYINFuw+n9AZhPBKQ==
dependencies:
"@typescript-eslint/experimental-utils" "4.8.2"
"@typescript-eslint/scope-manager" "4.8.2"
debug "^4.1.1"
functional-red-black-tree "^1.0.1"
regexpp "^3.0.0"
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/experimental-utils@4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.0.0.tgz#fbec21a3b5ab59127edb6ce2e139ed378cc50eb5"
integrity sha512-hbX6zR+a/vcpFVNJYN/Nbd7gmaMosDTxHEKcvmhWeWcq/0UDifrqmCfkkodbAKL46Fn4ekSBMTyq2zlNDzcQxw==
"@typescript-eslint/experimental-utils@4.12.0":
version "4.12.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.12.0.tgz#372838e76db76c9a56959217b768a19f7129546b"
integrity sha512-MpXZXUAvHt99c9ScXijx7i061o5HEjXltO+sbYfZAAHxv3XankQkPaNi5myy0Yh0Tyea3Hdq1pi7Vsh0GJb0fA==
dependencies:
"@types/json-schema" "^7.0.3"
"@typescript-eslint/scope-manager" "4.0.0"
"@typescript-eslint/types" "4.0.0"
"@typescript-eslint/typescript-estree" "4.0.0"
eslint-scope "^5.0.0"
eslint-utils "^2.0.0"
"@typescript-eslint/experimental-utils@4.8.2":
version "4.8.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.8.2.tgz#8909a5732f19329cf5ef0c39766170476bff5e50"
integrity sha512-hpTw6o6IhBZEsQsjuw/4RWmceRyESfAiEzAEnXHKG1X7S5DXFaZ4IO1JO7CW1aQ604leQBzjZmuMI9QBCAJX8Q==
dependencies:
"@types/json-schema" "^7.0.3"
"@typescript-eslint/scope-manager" "4.8.2"
"@typescript-eslint/types" "4.8.2"
"@typescript-eslint/typescript-estree" "4.8.2"
"@typescript-eslint/scope-manager" "4.12.0"
"@typescript-eslint/types" "4.12.0"
"@typescript-eslint/typescript-estree" "4.12.0"
eslint-scope "^5.0.0"
eslint-utils "^2.0.0"
@ -1852,13 +1827,13 @@
"@typescript-eslint/typescript-estree" "4.8.2"
debug "^4.1.1"
"@typescript-eslint/scope-manager@4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.0.0.tgz#8c9e3b3b8cdf5a1fbe671d9fad73ff67bc027ea8"
integrity sha512-9gcWUPoWo7gk/+ZQPg7L1ySRmR5HLIy3Vu6/LfhQbuzIkGm6v2CGIjpVRISoDLFRovNRDImd4aP/sa8O4yIEBg==
"@typescript-eslint/scope-manager@4.12.0":
version "4.12.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.12.0.tgz#beeb8beca895a07b10c593185a5612f1085ef279"
integrity sha512-QVf9oCSVLte/8jvOsxmgBdOaoe2J0wtEmBr13Yz0rkBNkl5D8bfnf6G4Vhox9qqMIoG7QQoVwd2eG9DM/ge4Qg==
dependencies:
"@typescript-eslint/types" "4.0.0"
"@typescript-eslint/visitor-keys" "4.0.0"
"@typescript-eslint/types" "4.12.0"
"@typescript-eslint/visitor-keys" "4.12.0"
"@typescript-eslint/scope-manager@4.8.2":
version "4.8.2"
@ -1868,23 +1843,23 @@
"@typescript-eslint/types" "4.8.2"
"@typescript-eslint/visitor-keys" "4.8.2"
"@typescript-eslint/types@4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.0.0.tgz#ec1f9fc06b8558a1d5afa6e337182d08beece7f5"
integrity sha512-bK+c2VLzznX2fUWLK6pFDv3cXGTp7nHIuBMq1B9klA+QCsqLHOOqe5TQReAQDl7DN2RfH+neweo0oC5hYlG7Rg==
"@typescript-eslint/types@4.12.0":
version "4.12.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.12.0.tgz#fb891fe7ccc9ea8b2bbd2780e36da45d0dc055e5"
integrity sha512-N2RhGeheVLGtyy+CxRmxdsniB7sMSCfsnbh8K/+RUIXYYq3Ub5+sukRCjVE80QerrUBvuEvs4fDhz5AW/pcL6g==
"@typescript-eslint/types@4.8.2":
version "4.8.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.8.2.tgz#c862dd0e569d9478eb82d6aee662ea53f5661a36"
integrity sha512-z1/AVcVF8ju5ObaHe2fOpZYEQrwHyZ7PTOlmjd3EoFeX9sv7UekQhfrCmgUO7PruLNfSHrJGQvrW3Q7xQ8EoAw==
"@typescript-eslint/typescript-estree@4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.0.0.tgz#2244c63de2f2190bc5718eb0fb3fd2c437d42097"
integrity sha512-ewFMPi2pMLDNIXGMPdf8r7El2oPSZw9PEYB0j+WcpKd7AX2ARmajGa7RUHTukllWX2bj4vWX6JLE1Oih2BMokA==
"@typescript-eslint/typescript-estree@4.12.0":
version "4.12.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.12.0.tgz#3963418c850f564bdab3882ae23795d115d6d32e"
integrity sha512-gZkFcmmp/CnzqD2RKMich2/FjBTsYopjiwJCroxqHZIY11IIoN0l5lKqcgoAPKHt33H2mAkSfvzj8i44Jm7F4w==
dependencies:
"@typescript-eslint/types" "4.0.0"
"@typescript-eslint/visitor-keys" "4.0.0"
"@typescript-eslint/types" "4.12.0"
"@typescript-eslint/visitor-keys" "4.12.0"
debug "^4.1.1"
globby "^11.0.1"
is-glob "^4.0.1"
@ -1906,12 +1881,12 @@
semver "^7.3.2"
tsutils "^3.17.1"
"@typescript-eslint/visitor-keys@4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.0.0.tgz#e2bbb69d98076d6a3f06abcb2048225a74362c33"
integrity sha512-sTouJbv6rjVJeTE4lpSBVYXq/u5K3gbB6LKt7ccFEZPTZB/VeQ0ssUz9q5Hx++sCqBbdF8PzrrgvEnicXAR6NQ==
"@typescript-eslint/visitor-keys@4.12.0":
version "4.12.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.12.0.tgz#a470a79be6958075fa91c725371a83baf428a67a"
integrity sha512-hVpsLARbDh4B9TKYz5cLbcdMIOAoBYgFPCSP9FFS/liSF+b33gVNq8JHY3QGhHNVz85hObvL7BEYLlgx553WCw==
dependencies:
"@typescript-eslint/types" "4.0.0"
"@typescript-eslint/types" "4.12.0"
eslint-visitor-keys "^2.0.0"
"@typescript-eslint/visitor-keys@4.8.2":
@ -3463,10 +3438,10 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
inherits "^2.0.1"
safe-buffer "^5.0.1"
circular-dependency-plugin@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz#e09dbc2dd3e2928442403e2d45b41cea06bc0a93"
integrity sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==
circular-dependency-plugin@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz#39e836079db1d3cf2f988dc48c5188a44058b600"
integrity sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ==
class-utils@^0.3.5:
version "0.3.6"
@ -4254,27 +4229,13 @@ debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6:
dependencies:
ms "^2.1.1"
debug@^4.0.1, debug@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
dependencies:
ms "^2.1.1"
debug@^4.1.1:
debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
dependencies:
ms "2.1.2"
debug@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1"
integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==
dependencies:
ms "2.1.2"
debuglog@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
@ -13803,10 +13764,10 @@ uuid@^7.0.3:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b"
integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==
uuid@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d"
integrity sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==
uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-compile-cache@2.0.3:
version "2.0.3"