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

This commit is contained in:
Roman committed 2023-02-14 12:36:00 +02:00
commit 440ca8c40f
30 files changed
+3075 -186

No files matched your search

+3 -3
View File
@@ -252,8 +252,8 @@
"@types/webpack-dev-server": "^4.7.2",
"@types/webpack-env": "^1.18.0",
"@types/webpack-node-externals": "^2.5.3",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"@typescript-eslint/eslint-plugin": "^5.51.0",
"@typescript-eslint/parser": "^5.51.0",
"adr": "^1.4.3",
"ansi_up": "^5.1.0",
"chalk": "^4.1.2",
@@ -269,7 +269,7 @@
"electron": "^19.1.9",
"electron-builder": "^23.6.0",
"electron-notarize": "^0.3.0",
"esbuild": "^0.17.5",
"esbuild": "^0.17.7",
"esbuild-loader": "^2.21.0",
"eslint": "^8.33.0",
"eslint-import-resolver-typescript": "^3.5.3",
@@ -33,6 +33,20 @@ export class Namespace extends KubeObject<
getStatus() {
return this.status?.phase ?? "-";
}
isSubnamespace() {
return this.getAnnotations().find(annotation => annotation.includes("hnc.x-k8s.io/subnamespace-of"));
}
isChildOf(parentName: string) {
return this.getLabels().find(label => label === `${parentName}.tree.hnc.x-k8s.io/depth=1`);
}
isControlledByHNC() {
const hierarchicalNamesaceControllerLabel = "hnc.x-k8s.io/included-namespace=true";
return this.getLabels().find(label => label === hierarchicalNamesaceControllerLabel);
}
}
export class NamespaceApi extends KubeApi<Namespace> {
@@ -23,7 +23,7 @@ export const defaultTerminalConfig: TerminalConfig = {
fontFamily: defaultTerminalFontFamily,
};
interface BaseEditorConfiguration extends Required<Pick<editor.IStandaloneEditorConstructionOptions, "minimap" | "tabSize" | "fontSize" | "fontFamily">> {
export interface BaseEditorConfiguration extends Required<Pick<editor.IStandaloneEditorConstructionOptions, "minimap" | "tabSize" | "fontSize" | "fontFamily">> {
lineNumbers: NonNullable<Exclude<editor.IStandaloneEditorConstructionOptions["lineNumbers"], Function>>;
}
@@ -10119,11 +10119,11 @@ exports[`cluster/namespaces - edit namespace from new tab when navigating to nam
class="footer"
>
<div
class="Dock"
class="Dock isOpen"
tabindex="-1"
>
<div
class="ResizingAnchor vertical leading disabled"
class="ResizingAnchor vertical leading"
/>
<div
class="tabs-container flex align-center"
@@ -10134,10 +10134,63 @@ exports[`cluster/namespaces - edit namespace from new tab when navigating to nam
>
<div
class="Tabs tabs"
/>
>
<div
class="Tab flex gaps align-center DockTab active"
data-testid="dock-tab-for-some-first-tab-id"
id="tab-some-first-tab-id"
role="tab"
tabindex="0"
>
<i
class="Icon material focusable small"
>
<span
class="icon"
data-icon-name="edit"
>
edit
</span>
</i>
<div
class="label"
>
<div
class="flex align-center"
>
<span
class="title"
>
Namespace: some-name
</span>
<div
class="close"
>
<i
class="Icon material interactive focusable small"
data-testid="dock-tab-close-for-some-first-tab-id"
tabindex="0"
>
<span
class="icon"
data-icon-name="close"
>
close
</span>
</i>
<div
data-testid="tooltip-content-for-dock-tab-close-for-some-first-tab-id"
>
Close ⌘+W
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class="toolbar flex gaps align-center box grow pl-0"
class="toolbar flex gaps align-center box grow"
>
<div
class="dock-menu box grow"
@@ -10158,6 +10211,118 @@ exports[`cluster/namespaces - edit namespace from new tab when navigating to nam
New tab
</div>
</div>
<i
class="Icon material interactive focusable"
tabindex="0"
>
<span
class="icon"
data-icon-name="fullscreen"
>
fullscreen
</span>
</i>
<div>
Fit to window
</div>
<i
class="Icon material interactive focusable"
tabindex="0"
>
<span
class="icon"
data-icon-name="keyboard_arrow_down"
>
keyboard_arrow_down
</span>
</i>
<div>
Minimize
</div>
</div>
</div>
<div
class="tab-content edit-resource"
data-testid="dock-tab-content-for-some-first-tab-id"
style="flex-basis: 300px;"
>
<div
class="EditResource flex column"
>
<div
class="InfoPanel flex gaps align-center"
>
<div
class="controls"
>
<div
class="resource-info flex gaps align-center"
>
<span>
Kind:
</span>
<div
class="badge"
>
Namespace
</div>
<span>
Name:
</span>
<div
class="badge"
>
some-name
</div>
<span>
Namespace:
</span>
<div
class="badge"
>
default
</div>
</div>
</div>
<div
class="flex gaps align-center"
/>
<button
class="Button plain"
data-testid="cancel-edit-resource-from-tab-for-some-first-tab-id"
type="button"
>
Cancel
</button>
<button
class="Button active outlined"
data-testid="save-edit-resource-from-tab-for-some-first-tab-id"
type="button"
>
Save
</button>
<button
class="Button primary active"
data-testid="save-and-close-edit-resource-from-tab-for-some-first-tab-id"
type="button"
>
Save & Close
</button>
</div>
<textarea
data-testid="monaco-editor-for-some-first-tab-id"
>
apiVersion: some-api-version
kind: Namespace
metadata:
uid: some-uid
name: some-name
resourceVersion: some-resource-version
selfLink: /apis/some-api-version/namespaces/some-uid
somePropertyToBeRemoved: some-value
somePropertyToBeChanged: some-old-value
</textarea>
</div>
</div>
</div>
@@ -401,8 +401,7 @@ metadata:
expect(rendered.baseElement).toMatchSnapshot();
});
// TODO: Not doable at the moment because info panel controls closing of the tab
xit("does not close the dock tab", () => {
it("does not close the dock tab", () => {
expect(
rendered.getByTestId("dock-tab-for-some-first-tab-id"),
).toBeInTheDocument();
@@ -11,7 +11,7 @@ const apiBaseHostHeaderInjectable = getInjectable({
instantiate: (di) => {
const lensProxyPort = di.inject(lensProxyPortInjectable);
return `localhost:${lensProxyPort.get()}`;
return `lens.app:${lensProxyPort.get()}`;
},
injectionToken: apiBaseHostHeaderInjectionToken,
});
@@ -2,7 +2,6 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { SelfSignedCert } from "selfsigned";
import { lensProxyCertificateChannel } from "../../common/certificate/lens-proxy-certificate-channel";
import { getRequestChannelListenerInjectable } from "../utils/channel/channel-listeners/listener-tokens";
import lensProxyCertificateInjectable from "../../common/certificate/lens-proxy-certificate.injectable";
@@ -10,7 +9,7 @@ import lensProxyCertificateInjectable from "../../common/certificate/lens-proxy-
const lensProxyCertificateRequestHandlerInjectable = getRequestChannelListenerInjectable({
channel: lensProxyCertificateChannel,
handler: (di) => {
const lensProxyCertificate = di.inject(lensProxyCertificateInjectable).get() as SelfSignedCert;
const lensProxyCertificate = di.inject(lensProxyCertificateInjectable).get();
return () => ({
cert: lensProxyCertificate.cert,
@@ -0,0 +1,937 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<NamespaceTreeView /> collapses item by clicking minus button 1`] = `
<body>
<div>
<div
class="TreeView"
data-testid="namespace-tree-view"
>
<div
class="DrawerTitle title"
>
Tree View
</div>
<ul
aria-multiselectable="false"
class="MuiTreeView-root"
role="tree"
>
<li
aria-expanded="true"
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-levels-deep"
role="treeitem"
tabindex="0"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
levels-deep
</div>
</div>
<ul
class="MuiCollapse-root MuiTreeItem-group group MuiCollapse-entered"
role="group"
style="min-height: 0px;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-level-deep-child-a"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
level-deep-child-a
</div>
</div>
</li>
<li
aria-expanded="false"
class="MuiTreeItem-root"
data-testid="namespace-level-deep-child-b"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="plus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 12.977h-4.923v4.896q0 .401-.281.682t-.682.281v0q-.375 0-.669-.281t-.294-.682v-4.896h-4.923q-.401 0-.682-.294t-.281-.669v0q0-.401.281-.682t.682-.281h4.923v-4.896q0-.401.294-.682t.669-.281v0q.401 0 .682.281t.281.682v4.896h4.923q.401 0 .682.281t.281.682v0q0 .375-.281.669t-.682.294z"
/>
</svg>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
level-deep-child-b
</div>
</div>
<ul
class="MuiCollapse-root MuiTreeItem-group group"
role="group"
style="min-height: 0px; height: 0px; transition-duration: 300ms;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-level-deep-subchild-a"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
level-deep-subchild-a
</div>
</div>
</li>
</div>
</div>
</ul>
</li>
</div>
</div>
</ul>
</li>
</ul>
</div>
</div>
</body>
`;
exports[`<NamespaceTreeView /> expands item by clicking plus button 1`] = `
<body>
<div>
<div
class="TreeView"
data-testid="namespace-tree-view"
>
<div
class="DrawerTitle title"
>
Tree View
</div>
<ul
aria-multiselectable="false"
class="MuiTreeView-root"
role="tree"
>
<li
aria-expanded="true"
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-levels-deep"
role="treeitem"
tabindex="0"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
levels-deep
</div>
</div>
<ul
class="MuiCollapse-root MuiTreeItem-group group MuiCollapse-entered"
role="group"
style="min-height: 0px;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-level-deep-child-a"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
level-deep-child-a
</div>
</div>
</li>
<li
aria-expanded="true"
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-level-deep-child-b"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
level-deep-child-b
</div>
</div>
<ul
class="MuiCollapse-root MuiTreeItem-group group"
role="group"
style="min-height: 0px; height: 0px; transition-duration: 300ms;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-level-deep-subchild-a"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
level-deep-subchild-a
</div>
</div>
</li>
</div>
</div>
</ul>
</li>
</div>
</div>
</ul>
</li>
</ul>
</div>
</div>
</body>
`;
exports[`<NamespaceTreeView /> renders 2 levels deep 1`] = `
<body>
<div>
<div
class="TreeView"
data-testid="namespace-tree-view"
>
<div
class="DrawerTitle title"
>
Tree View
</div>
<ul
aria-multiselectable="false"
class="MuiTreeView-root"
role="tree"
>
<li
aria-expanded="true"
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-levels-deep"
role="treeitem"
tabindex="0"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
levels-deep
</div>
</div>
<ul
class="MuiCollapse-root MuiTreeItem-group group MuiCollapse-entered"
role="group"
style="min-height: 0px;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-level-deep-child-a"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
level-deep-child-a
</div>
</div>
</li>
<li
aria-expanded="true"
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-level-deep-child-b"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
level-deep-child-b
</div>
</div>
<ul
class="MuiCollapse-root MuiTreeItem-group group MuiCollapse-entered"
role="group"
style="min-height: 0px;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-level-deep-subchild-a"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
level-deep-subchild-a
</div>
</div>
</li>
</div>
</div>
</ul>
</li>
</div>
</div>
</ul>
</li>
</ul>
</div>
</div>
</body>
`;
exports[`<NamespaceTreeView /> renders namespace with 2 children namespaces 1`] = `
<body>
<div>
<div
class="TreeView"
data-testid="namespace-tree-view"
>
<div
class="DrawerTitle title"
>
Tree View
</div>
<ul
aria-multiselectable="false"
class="MuiTreeView-root"
role="tree"
>
<li
aria-expanded="true"
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-acme-org"
role="treeitem"
tabindex="0"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
acme-org
</div>
</div>
<ul
class="MuiCollapse-root MuiTreeItem-group group MuiCollapse-entered"
role="group"
style="min-height: 0px;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-team-a"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
team-a
</div>
</div>
</li>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-team-b"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
team-b
</div>
</div>
</li>
</div>
</div>
</ul>
</li>
</ul>
</div>
</div>
</body>
`;
exports[`<NamespaceTreeView /> renders namespace with children namespaces and a subnamespace 1`] = `
<body>
<div>
<div
class="TreeView"
data-testid="namespace-tree-view"
>
<div
class="DrawerTitle title"
>
Tree View
</div>
<ul
aria-multiselectable="false"
class="MuiTreeView-root"
role="tree"
>
<li
aria-expanded="true"
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-org-a"
role="treeitem"
tabindex="0"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
org-a
</div>
</div>
<ul
class="MuiCollapse-root MuiTreeItem-group group MuiCollapse-entered"
role="group"
style="min-height: 0px;"
>
<div
class="MuiCollapse-wrapper"
>
<div
class="MuiCollapse-wrapperInner"
>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-team-c"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
team-c
</div>
</div>
</li>
<li
class="MuiTreeItem-root Mui-expanded"
data-testid="namespace-service-1"
role="treeitem"
tabindex="-1"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
service-1
<span
class="subnamespaceBadge"
data-testid="namespace-details-badge-for-service-1"
id="namespace-details-badge-for-service-1"
>
S
</span>
</div>
</div>
</li>
</div>
</div>
</ul>
</li>
</ul>
</div>
</div>
</body>
`;
exports[`<NamespaceTreeView /> renders one namespace without children 1`] = `
<body>
<div>
<div
class="TreeView"
data-testid="namespace-tree-view"
>
<div
class="DrawerTitle title"
>
Tree View
</div>
<ul
aria-multiselectable="false"
class="MuiTreeView-root"
role="tree"
>
<li
class="MuiTreeItem-root"
data-testid="namespace-single-root"
role="treeitem"
tabindex="0"
>
<div
class="MuiTreeItem-content"
>
<div
class="MuiTreeItem-iconContainer"
>
<div
style="opacity: 0.3;"
>
<svg
aria-hidden="true"
class="MuiSvgIcon-root"
data-testid="minus-square"
focusable="false"
style="width: 14px; height: 14px;"
viewBox="0 0 24 24"
>
<path
d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z"
/>
</svg>
</div>
</div>
<div
class="MuiTypography-root MuiTreeItem-label label MuiTypography-body1"
>
single-root
</div>
</div>
</li>
</ul>
</div>
</div>
</body>
`;
@@ -0,0 +1,18 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import namespaceStoreInjectable from "./store.injectable";
const hierarchicalNamespacesInjectable = getInjectable({
id: "hierarchical-namespaces",
instantiate: (di) => {
const namespaceStore = di.inject(namespaceStoreInjectable);
return namespaceStore.items.filter(item => item.isControlledByHNC());
},
});
export default hierarchicalNamespacesInjectable;
@@ -26,6 +26,9 @@ import limitRangeStoreInjectable from "../+config-limit-ranges/store.injectable"
import resourceQuotaStoreInjectable from "../+config-resource-quotas/store.injectable";
import type { Logger } from "../../../common/logger";
import loggerInjectable from "../../../common/logger.injectable";
import { NamespaceTreeView } from "./namespace-tree-view";
import namespaceStoreInjectable from "./store.injectable";
import type { NamespaceStore } from "./store";
export interface NamespaceDetailsProps extends KubeObjectDetailsProps<Namespace> {
}
@@ -35,6 +38,7 @@ interface Dependencies {
getDetailsUrl: GetDetailsUrl;
resourceQuotaStore: ResourceQuotaStore;
limitRangeStore: LimitRangeStore;
namespaceStore: NamespaceStore;
logger: Logger;
}
@@ -103,6 +107,10 @@ class NonInjectedNamespaceDetails extends React.Component<NamespaceDetailsProps
</Link>
))}
</DrawerItem>
{namespace.isControlledByHNC() && (
<NamespaceTreeView tree={this.props.namespaceStore.getNamespaceTree(namespace)}/>
)}
</div>
);
}
@@ -115,6 +123,7 @@ export const NamespaceDetails = withInjectables<Dependencies, NamespaceDetailsPr
getDetailsUrl: di.inject(getDetailsUrlInjectable),
limitRangeStore: di.inject(limitRangeStoreInjectable),
resourceQuotaStore: di.inject(resourceQuotaStoreInjectable),
namespaceStore: di.inject(namespaceStoreInjectable),
logger: di.inject(loggerInjectable),
}),
});
@@ -0,0 +1,205 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { DiContainer } from "@ogre-tools/injectable";
import { observable } from "mobx";
import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import { Namespace } from "../../../common/k8s-api/endpoints";
import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable";
import createClusterInjectable from "../../cluster/create-cluster.injectable";
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-created.injectable";
import type { NamespaceStore } from "./store";
import namespaceStoreInjectable from "./store.injectable";
function createNamespace(name: string, labels?: Record<string, string>, annotations?: Record<string, string>): Namespace {
return new Namespace({
apiVersion: "v1",
kind: "Namespace",
metadata: {
name,
resourceVersion: "1",
selfLink: `/api/v1/namespaces/${name}`,
uid: `${name}`,
labels: {
...labels,
},
annotations: {
...annotations,
},
},
});
}
const singleRoot = createNamespace("single-root", {
"hnc.x-k8s.io/included-namespace": "true",
});
const acmeGroup = createNamespace("acme-org", {
"hnc.x-k8s.io/included-namespace": "true",
});
const orgA = createNamespace("org-a", {
"hnc.x-k8s.io/included-namespace": "true",
});
const teamA = createNamespace("team-a", {
"hnc.x-k8s.io/included-namespace": "true",
"acme-org.tree.hnc.x-k8s.io/depth": "1",
"kubernetes.io/metadata.name": "team-a",
"team-a.tree.hnc.x-k8s.io/depth": "0",
});
const teamB = createNamespace("team-b", {
"hnc.x-k8s.io/included-namespace": "true",
"acme-org.tree.hnc.x-k8s.io/depth": "1",
"kubernetes.io/metadata.name": "team-b",
"team-b.tree.hnc.x-k8s.io/depth": "0",
});
const teamC = createNamespace("team-c", {
"hnc.x-k8s.io/included-namespace": "true",
"org-a.tree.hnc.x-k8s.io/depth": "1",
"kubernetes.io/metadata.name": "team-c",
"team-c.tree.hnc.x-k8s.io/depth": "0",
});
const service1 = createNamespace("service-1", {
"hnc.x-k8s.io/included-namespace": "true",
"org-a.tree.hnc.x-k8s.io/depth": "1",
"kubernetes.io/metadata.name": "team-c",
"service-1.tree.hnc.x-k8s.io/depth": "0",
}, {
"hnc.x-k8s.io/subnamespace-of": "org-a",
});
const levelsDeep = createNamespace("levels-deep", {
"hnc.x-k8s.io/included-namespace": "true",
});
const levelDeepChildA = createNamespace("level-deep-child-a", {
"hnc.x-k8s.io/included-namespace": "true",
"levels-deep.tree.hnc.x-k8s.io/depth": "1",
"level-deep-child-a.tree.hnc.x-k8s.io/depth": "0",
});
const levelDeepChildB = createNamespace("level-deep-child-b", {
"hnc.x-k8s.io/included-namespace": "true",
"levels-deep.tree.hnc.x-k8s.io/depth": "1",
"level-deep-child-b.tree.hnc.x-k8s.io/depth": "0",
});
const levelDeepSubChildA = createNamespace("level-deep-subchild-a", {
"hnc.x-k8s.io/included-namespace": "true",
"levels-deep.tree.hnc.x-k8s.io/depth": "2",
"level-deep-child-b.tree.hnc.x-k8s.io/depth": "1",
"level-deep-subchild-a.tree.hnc.x-k8s.io/depth": "0",
});
describe("NamespaceStore", () => {
let di: DiContainer;
let namespaceStore: NamespaceStore;
beforeEach(async () => {
di = getDiForUnitTesting({ doGeneralOverrides: true });
di.override(directoryForUserDataInjectable, () => "/some-user-store-path");
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
di.override(storesAndApisCanBeCreatedInjectable, () => true);
const createCluster = di.inject(createClusterInjectable);
di.override(hostedClusterInjectable, () => createCluster({
contextName: "some-context-name",
id: "some-cluster-id",
kubeConfigPath: "/some-path-to-a-kubeconfig",
}, {
clusterServerUrl: "https://localhost:8080",
}));
namespaceStore = di.inject(namespaceStoreInjectable);
namespaceStore.items = observable.array([
acmeGroup,
orgA,
teamA,
teamB,
teamC,
service1,
levelsDeep,
levelDeepChildA,
levelDeepChildB,
levelDeepSubChildA,
]);
});
it("returns tree for single node", () => {
const tree = namespaceStore.getNamespaceTree(service1);
expect(tree).toEqual({
id: "service-1",
namespace: service1,
children: [],
});
});
it("returns tree for namespace not listed in store", () => {
const tree = namespaceStore.getNamespaceTree(singleRoot);
expect(tree).toEqual({
id: "single-root",
namespace: singleRoot,
children: [],
});
});
it("return tree for namespace with children", () => {
const tree = namespaceStore.getNamespaceTree(acmeGroup);
expect(tree).toEqual({
id: "acme-org",
namespace: acmeGroup,
children: [
{
id: "team-a",
namespace: teamA,
children: [],
},
{
id: "team-b",
namespace: teamB,
children: [],
},
],
});
});
it("return tree for namespace with deep nested children", () => {
const tree = namespaceStore.getNamespaceTree(levelsDeep);
expect(tree).toEqual({
id: "levels-deep",
namespace: levelsDeep,
children: [
{
id: "level-deep-child-a",
namespace: levelDeepChildA,
children: [],
},
{
id: "level-deep-child-b",
namespace: levelDeepChildB,
children: [{
id: "level-deep-subchild-a",
namespace: levelDeepSubChildA,
children: [],
}],
},
],
});
});
});
@@ -0,0 +1,14 @@
.TreeView {
.group {
margin-inline-start: var(--margin);
padding-inline-start: calc(var(--padding) * 2);
border-inline-start: 1px dashed var(--borderColor);
}
.label {
font-size: inherit;
line-height: 1.8;
cursor: default;
background-color: transparent!important;
}
}
@@ -0,0 +1,334 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { DiContainer } from "@ogre-tools/injectable";
import { fireEvent } from "@testing-library/react";
import React from "react";
import { Namespace } from "../../../common/k8s-api/endpoints";
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
import type { DiRender } from "../test-utils/renderFor";
import { renderFor } from "../test-utils/renderFor";
import hierarchicalNamespacesInjectable from "./hierarchical-namespaces.injectable";
import { NamespaceTreeView } from "./namespace-tree-view";
import type { NamespaceTree } from "./store";
jest.mock("react-router-dom", () => ({
Link: ({ children }: { children: React.ReactNode }) => children,
}));
function createNamespace(name: string, labels?: Record<string, string>, annotations?: Record<string, string>): Namespace {
return new Namespace({
apiVersion: "v1",
kind: "Namespace",
metadata: {
name,
resourceVersion: "1",
selfLink: `/api/v1/namespaces/${name}`,
uid: `${name}`,
labels: {
...labels,
},
annotations: {
...annotations,
},
},
});
}
const singleRoot = createNamespace("single-root", {
"hnc.x-k8s.io/included-namespace": "true",
});
const acmeGroup = createNamespace("acme-org", {
"hnc.x-k8s.io/included-namespace": "true",
});
const orgA = createNamespace("org-a", {
"hnc.x-k8s.io/included-namespace": "true",
});
const teamA = createNamespace("team-a", {
"hnc.x-k8s.io/included-namespace": "true",
"acme-org.tree.hnc.x-k8s.io/depth": "1",
"kubernetes.io/metadata.name": "team-a",
"team-a.tree.hnc.x-k8s.io/depth": "0",
});
const teamB = createNamespace("team-b", {
"hnc.x-k8s.io/included-namespace": "true",
"acme-org.tree.hnc.x-k8s.io/depth": "1",
"kubernetes.io/metadata.name": "team-b",
"team-b.tree.hnc.x-k8s.io/depth": "0",
});
const teamC = createNamespace("team-c", {
"hnc.x-k8s.io/included-namespace": "true",
"org-a.tree.hnc.x-k8s.io/depth": "1",
"kubernetes.io/metadata.name": "team-c",
"team-c.tree.hnc.x-k8s.io/depth": "0",
});
const service1 = createNamespace("service-1", {
"hnc.x-k8s.io/included-namespace": "true",
"org-a.tree.hnc.x-k8s.io/depth": "1",
"kubernetes.io/metadata.name": "team-c",
"service-1.tree.hnc.x-k8s.io/depth": "0",
}, {
"hnc.x-k8s.io/subnamespace-of": "org-a",
});
const levelsDeep = createNamespace("levels-deep", {
"hnc.x-k8s.io/included-namespace": "true",
});
const levelDeepChildA = createNamespace("level-deep-child-a", {
"hnc.x-k8s.io/included-namespace": "true",
"levels-deep.tree.hnc.x-k8s.io/depth": "1",
"level-deep-child-a.tree.hnc.x-k8s.io/depth": "0",
});
const levelDeepChildB = createNamespace("level-deep-child-b", {
"hnc.x-k8s.io/included-namespace": "true",
"levels-deep.tree.hnc.x-k8s.io/depth": "1",
"level-deep-child-b.tree.hnc.x-k8s.io/depth": "0",
});
const levelDeepSubChildA = createNamespace("level-deep-subchild-a", {
"hnc.x-k8s.io/included-namespace": "true",
"levels-deep.tree.hnc.x-k8s.io/depth": "2",
"level-deep-child-b.tree.hnc.x-k8s.io/depth": "1",
"level-deep-subchild-a.tree.hnc.x-k8s.io/depth": "0",
});
describe("<NamespaceTreeView />", () => {
let di: DiContainer;
let render: DiRender;
beforeEach(async () => {
di = getDiForUnitTesting({ doGeneralOverrides: true });
di.override(hierarchicalNamespacesInjectable, () => [
acmeGroup,
orgA,
teamA,
teamB,
teamC,
service1,
levelsDeep,
levelDeepChildA,
levelDeepChildB,
levelDeepSubChildA,
]);
render = renderFor(di);
});
it("renders one namespace without children", () => {
const tree: NamespaceTree = {
id: "single-root",
namespace: singleRoot,
};
const result = render(<NamespaceTreeView tree={tree} />);
expect(result.baseElement).toMatchSnapshot();
});
it("renders namespace with 2 children namespaces", () => {
const tree: NamespaceTree = {
id: "acme-org",
namespace: acmeGroup,
children: [
{
id: "team-a",
namespace: teamA,
},
{
id: "team-b",
namespace: teamB,
},
],
};
const result = render(<NamespaceTreeView tree={tree} />);
expect(result.baseElement).toMatchSnapshot();
});
it("renders namespace with children namespaces and a subnamespace", () => {
const tree: NamespaceTree = {
id: "org-a",
namespace: orgA,
children: [
{
id: "team-c",
namespace: teamC,
},
{
id: "service-1",
namespace: service1,
},
],
};
const result = render(<NamespaceTreeView tree={tree} />);
expect(result.baseElement).toMatchSnapshot();
});
it("renders an indicator badge for the subnamespace", () => {
const tree: NamespaceTree = {
id: "org-a",
namespace: orgA,
children: [
{
id: "team-c",
namespace: teamC,
},
{
id: "service-1",
namespace: service1,
},
],
};
const result = render(<NamespaceTreeView tree={tree} />);
expect(result.getByTestId("namespace-details-badge-for-service-1")).toBeInTheDocument();
});
it("does not render an indicator badge for the true namespace", () => {
const tree: NamespaceTree = {
id: "org-a",
namespace: orgA,
children: [
{
id: "team-c",
namespace: teamC,
},
{
id: "service-1",
namespace: service1,
},
],
};
const result = render(<NamespaceTreeView tree={tree} />);
const trueNamespace = result.getByTestId("namespace-team-c");
expect(trueNamespace.querySelector("[data-testid='namespace-details-badge-for-team-c']")).toBeNull();
});
it("renders 2 levels deep", () => {
const tree: NamespaceTree = {
id: "levels-deep",
namespace: levelsDeep,
children: [
{
id: "level-deep-child-a",
namespace: levelDeepChildA,
},
{
id: "level-deep-child-b",
namespace: levelDeepChildB,
children: [{
id: "level-deep-subchild-a",
namespace: levelDeepSubChildA,
}],
},
],
};
const result = render(<NamespaceTreeView tree={tree} />);
expect(result.baseElement).toMatchSnapshot();
});
it("expands children items by default", () => {
const tree: NamespaceTree = {
id: "levels-deep",
namespace: levelsDeep,
children: [
{
id: "level-deep-child-a",
namespace: levelDeepChildA,
},
{
id: "level-deep-child-b",
namespace: levelDeepChildB,
children: [{
id: "level-deep-subchild-a",
namespace: levelDeepSubChildA,
}],
},
],
};
const result = render(<NamespaceTreeView tree={tree} />);
const deepest = result.getByTestId("namespace-level-deep-child-b");
expect(deepest).toHaveAttribute("aria-expanded", "true");
});
it("collapses item by clicking minus button", () => {
const tree: NamespaceTree = {
id: "levels-deep",
namespace: levelsDeep,
children: [
{
id: "level-deep-child-a",
namespace: levelDeepChildA,
},
{
id: "level-deep-child-b",
namespace: levelDeepChildB,
children: [{
id: "level-deep-subchild-a",
namespace: levelDeepSubChildA,
}],
},
],
};
const result = render(<NamespaceTreeView tree={tree} />);
const levelB = result.getByTestId("namespace-level-deep-child-b");
const minusButton = levelB.querySelector("[data-testid='minus-square']");
if (minusButton) {
fireEvent.click(minusButton);
}
expect(result.baseElement).toMatchSnapshot();
});
it("expands item by clicking plus button", () => {
const tree: NamespaceTree = {
id: "levels-deep",
namespace: levelsDeep,
children: [
{
id: "level-deep-child-a",
namespace: levelDeepChildA,
},
{
id: "level-deep-child-b",
namespace: levelDeepChildB,
children: [{
id: "level-deep-subchild-a",
namespace: levelDeepSubChildA,
}],
},
],
};
const result = render(<NamespaceTreeView tree={tree} />);
const levelB = result.getByTestId("namespace-level-deep-child-b");
const minusButton = levelB.querySelector("[data-testid='minus-square']");
if (minusButton) {
fireEvent.click(minusButton);
}
const plusButton = levelB.querySelector("[data-testid='plus-square']");
if (plusButton) {
fireEvent.click(plusButton);
}
expect(result.baseElement).toMatchSnapshot();
});
});
@@ -0,0 +1,106 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import styles from "./namespace-tree-view.module.scss";
import { SvgIcon } from "@material-ui/core";
import { TreeItem, TreeView } from "@material-ui/lab";
import { withInjectables } from "@ogre-tools/injectable-react";
import React from "react";
import { Link } from "react-router-dom";
import type { Namespace } from "../../../common/k8s-api/endpoints";
import { DrawerTitle } from "../drawer";
import type { GetDetailsUrl } from "../kube-detail-params/get-details-url.injectable";
import getDetailsUrlInjectable from "../kube-detail-params/get-details-url.injectable";
import { SubnamespaceBadge } from "./subnamespace-badge";
import hierarchicalNamespacesInjectable from "./hierarchical-namespaces.injectable";
import { prevDefault } from "../../utils";
import type { NamespaceTree } from "./store";
interface NamespaceTreeViewProps {
tree: NamespaceTree;
}
interface Dependencies {
namespaces: Namespace[];
getDetailsUrl: GetDetailsUrl;
}
function NonInjectableNamespaceTreeView({ tree, namespaces, getDetailsUrl }: Dependencies & NamespaceTreeViewProps) {
const [expandedItems, setExpandedItems] = React.useState<string[]>(namespaces.map(ns => ns.getId()));
const classes = { group: styles.group, label: styles.label };
function renderTree(nodes: NamespaceTree) {
return (
<TreeItem
key={nodes.id}
nodeId={nodes.id}
data-testid={`namespace-${nodes.id}`}
classes={classes}
onIconClick={prevDefault(() => toggleNode(nodes.id))}
label={(
<>
<Link key={nodes.namespace.getId()} to={getDetailsUrl(nodes.namespace.selfLink)}>
{nodes.namespace.getName()}
</Link>
{" "}
{nodes.namespace.isSubnamespace() && (
<SubnamespaceBadge id={`namespace-details-badge-for-${nodes.namespace.getId()}`} />
)}
</>
)}
>
{Array.isArray(nodes.children) ? nodes.children.map((node) => renderTree(node)) : null}
</TreeItem>
);
}
function toggleNode(id: string) {
if (expandedItems.includes(id)) {
setExpandedItems(expandedItems.filter(item => item !== id));
} else {
setExpandedItems([...expandedItems, id]);
}
}
return (
<div data-testid="namespace-tree-view" className={styles.TreeView}>
<DrawerTitle>Tree View</DrawerTitle>
<TreeView
defaultExpanded={[tree.id]}
defaultCollapseIcon={<MinusSquareIcon />}
defaultExpandIcon={<PlusSquareIcon />}
defaultEndIcon={(<div style={{ opacity: 0.3 }}><MinusSquareIcon /></div>)}
expanded={expandedItems}
>
{renderTree(tree)}
</TreeView>
</div>
);
}
function MinusSquareIcon() {
return (
<SvgIcon style={{ width: 14, height: 14 }} data-testid="minus-square">
<path d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 11.023h-11.826q-.375 0-.669.281t-.294.682v0q0 .401.294 .682t.669.281h11.826q.375 0 .669-.281t.294-.682v0q0-.401-.294-.682t-.669-.281z" />
</SvgIcon>
);
}
function PlusSquareIcon() {
return (
<SvgIcon style={{ width: 14, height: 14 }} data-testid="plus-square">
<path d="M22.047 22.074v0 0-20.147 0h-20.12v0 20.147 0h20.12zM22.047 24h-20.12q-.803 0-1.365-.562t-.562-1.365v-20.147q0-.776.562-1.351t1.365-.575h20.147q.776 0 1.351.575t.575 1.351v20.147q0 .803-.575 1.365t-1.378.562v0zM17.873 12.977h-4.923v4.896q0 .401-.281.682t-.682.281v0q-.375 0-.669-.281t-.294-.682v-4.896h-4.923q-.401 0-.682-.294t-.281-.669v0q0-.401.281-.682t.682-.281h4.923v-4.896q0-.401.294-.682t.669-.281v0q.401 0 .682.281t.281.682v4.896h4.923q.401 0 .682.281t.281.682v0q0 .375-.281.669t-.682.294z" />
</SvgIcon>
);
}
export const NamespaceTreeView = withInjectables<Dependencies, NamespaceTreeViewProps>(NonInjectableNamespaceTreeView, {
getProps: (di, props) => ({
namespaces: di.inject(hierarchicalNamespacesInjectable),
getDetailsUrl: di.inject(getDetailsUrlInjectable),
...props,
}),
});
@@ -22,4 +22,8 @@
@include namespaceStatus;
}
}
.subnamespaceBadge {
margin-inline-start: var(--margin);
}
}
@@ -16,6 +16,7 @@ import { withInjectables } from "@ogre-tools/injectable-react";
import namespaceStoreInjectable from "./store.injectable";
import { KubeObjectAge } from "../kube-object/age";
import openAddNamepaceDialogInjectable from "./add-dialog/open.injectable";
import { SubnamespaceBadge } from "./subnamespace-badge";
enum columnId {
name = "name",
@@ -55,7 +56,12 @@ const NonInjectedNamespacesRoute = ({ namespaceStore, openAddNamespaceDialog }:
{ title: "Status", className: "status", sortBy: columnId.status, id: columnId.status },
]}
renderTableContents={namespace => [
namespace.getName(),
<>
{namespace.getName()}
{namespace.isSubnamespace() && (
<SubnamespaceBadge className="subnamespaceBadge" id={`namespace-list-badge-for-${namespace.getId()}`} />
)}
</>,
<KubeObjectStatusIcon key="icon" object={namespace} />,
namespace.getLabels().map(label => (
<Badge
@@ -12,6 +12,12 @@ import { KubeObjectStore } from "../../../common/k8s-api/kube-object.store";
import type { NamespaceApi } from "../../../common/k8s-api/endpoints/namespace.api";
import { Namespace } from "../../../common/k8s-api/endpoints/namespace.api";
export interface NamespaceTree {
id: string;
namespace: Namespace;
children?: NamespaceTree[];
}
interface Dependencies extends KubeObjectStoreDependencies {
readonly storage: StorageLayer<string[] | undefined>;
readonly clusterConfiguredAccessibleNamespaces: IComputedValue<string[]>;
@@ -202,6 +208,16 @@ export class NamespaceStore extends KubeObjectStore<Namespace, NamespaceApi> {
this.selectAll();
}
getNamespaceTree(root: Namespace): NamespaceTree {
const children = this.items.filter(namespace => namespace.isChildOf(root.getName()));
return {
id: root.getId(),
namespace: root,
children: children.map(this.getNamespaceTree),
};
}
@action
async remove(item: Namespace) {
await super.remove(item);
@@ -0,0 +1,11 @@
.subnamespaceBadge {
border-radius: 3px;
padding: 0px 4px;
border: 1px solid cadetblue;
color: cadetblue;
display: inline-flex;
font-size: x-small;
font-weight: bold;
height: 16px;
align-items: center;
}
@@ -0,0 +1,31 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import styles from "./subnamespace-badge.module.scss";
import React from "react";
import { Tooltip } from "../tooltip";
import { cssNames } from "../../utils";
interface SubnamespaceBadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
id: string;
}
export function SubnamespaceBadge({ id, className, ...other }: SubnamespaceBadgeProps) {
return (
<>
<span
className={cssNames(styles.subnamespaceBadge, className)}
data-testid={id}
id={id}
{...other}
>
S
</span>
<Tooltip targetId={id}>
Subnamespace
</Tooltip>
</>
);
}
@@ -76,7 +76,7 @@ class NonInjectedCreateResource extends React.Component<CreateResourceProps & De
this.error = error.toString();
};
create = async (): Promise<void> => {
create = async (): Promise<string | void> => {
const { apiManager, getDetailsUrl, navigate, requestKubeObjectCreation } = this.props;
if (this.error || !this.data?.trim()) {
@@ -98,7 +98,7 @@ class NonInjectedCreateResource extends React.Component<CreateResourceProps & De
this.props.logger.warn("Failed to create resource", { resource }, result.error);
this.props.showCheckedErrorNotification(result.error, "Unknown error occured while creating resources");
return;
throw result.error;
}
const { kind, apiVersion, metadata: { name, namespace }} = result.response;
@@ -122,7 +122,13 @@ class NonInjectedCreateResource extends React.Component<CreateResourceProps & De
));
});
await Promise.allSettled(creatingResources);
const results = await Promise.allSettled(creatingResources);
if (results.some(result => result.status === "rejected")) {
return;
}
return "All resources have been successfully created";
};
renderControls() {
@@ -174,5 +174,7 @@ export class EditResourceModel {
runInAction(() => {
this.editingResource.firstDraft = currentValue;
});
return result.response.toString();
};
}
@@ -93,18 +93,25 @@ class NonInjectedInfoPanel extends Component<InfoPanelProps & Dependencies> {
if (showNotifications && result) {
this.props.showSuccessNotification(result);
}
return result;
} catch (error) {
if (showNotifications) {
this.props.showCheckedErrorNotification(error, "Unknown error while submitting");
}
return false;
} finally {
this.waiting = false;
}
};
submitAndClose = async () => {
await this.submit();
this.close();
const result = await this.submit();
if (result) {
this.close();
}
};
close = () => {
+162 -162
View File
@@ -587,220 +587,220 @@
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz#cf91e86df127aa3d141744edafcba0abdc577d23"
integrity sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==
"@esbuild/android-arm64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.5.tgz#a145f43018e639bed94ed637369e2dcdd6bf9ea2"
integrity sha512-KHWkDqYAMmKZjY4RAN1PR96q6UOtfkWlTS8uEwWxdLtkRt/0F/csUhXIrVfaSIFxnscIBMPynGfhsMwQDRIBQw==
"@esbuild/android-arm64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.7.tgz#7d22b442815624423de5541545401e12a8d474d8"
integrity sha512-fOUBZvcbtbQJIj2K/LMKcjULGfXLV9R4qjXFsi3UuqFhIRJHz0Fp6kFjsMFI6vLuPrfC5G9Dmh+3RZOrSKY2Lg==
"@esbuild/android-arm@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.17.tgz#025b6246d3f68b7bbaa97069144fb5fb70f2fff2"
integrity sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==
"@esbuild/android-arm@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.5.tgz#9fa2deff7fc5d180bb4ecff70beea3a95ac44251"
integrity sha512-crmPUzgCmF+qZXfl1YkiFoUta2XAfixR1tEnr/gXIixE+WL8Z0BGqfydP5oox0EUOgQMMRgtATtakyAcClQVqQ==
"@esbuild/android-arm@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.7.tgz#fa30de0cfae8e8416c693dc449c415765542483b"
integrity sha512-Np6Lg8VUiuzHP5XvHU7zfSVPN4ILdiOhxA1GQ1uvCK2T2l3nI8igQV0c9FJx4hTkq8WGqhGEvn5UuRH8jMkExg==
"@esbuild/android-x64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.17.tgz#c820e0fef982f99a85c4b8bfdd582835f04cd96e"
integrity sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==
"@esbuild/android-x64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.5.tgz#145fc61f810400e65a56b275280d1422a102c2ef"
integrity sha512-8fI/AnIdmWz/+1iza2WrCw8kwXK9wZp/yZY/iS8ioC+U37yJCeppi9EHY05ewJKN64ASoBIseufZROtcFnX5GA==
"@esbuild/android-x64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.7.tgz#34a1af914510ec821246859f8ae7d8fe843dd37b"
integrity sha512-6YILpPvop1rPAvaO/n2iWQL45RyTVTR/1SK7P6Xi2fyu+hpEeX22fE2U2oJd1sfpovUJOWTRdugjddX6QCup3A==
"@esbuild/darwin-arm64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz#edef4487af6b21afabba7be5132c26d22379b220"
integrity sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==
"@esbuild/darwin-arm64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.5.tgz#61fb0546aa4bae0850817d6e0d008b1cb3f64b49"
integrity sha512-EAvaoyIySV6Iif3NQCglUNpnMfHSUgC5ugt2efl3+QDntucJe5spn0udNZjTgNi6tKVqSceOw9tQ32liNZc1Xw==
"@esbuild/darwin-arm64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.7.tgz#06712059a30a6130eef701fb634883a4aaea02f7"
integrity sha512-7i0gfFsDt1BBiurZz5oZIpzfxqy5QkJmhXdtrf2Hma/gI9vL2AqxHhRBoI1NeWc9IhN1qOzWZrslhiXZweMSFg==
"@esbuild/darwin-x64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz#42829168730071c41ef0d028d8319eea0e2904b4"
integrity sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==
"@esbuild/darwin-x64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.5.tgz#54b770f0c49f524ae9ba24c85d6dea8b521f610d"
integrity sha512-ha7QCJh1fuSwwCgoegfdaljowwWozwTDjBgjD3++WAy/qwee5uUi1gvOg2WENJC6EUyHBOkcd3YmLDYSZ2TPPA==
"@esbuild/darwin-x64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.7.tgz#58cd69d00d5b9847ad2015858a7ec3f10bf309ad"
integrity sha512-hRvIu3vuVIcv4SJXEKOHVsNssM5tLE2xWdb9ZyJqsgYp+onRa5El3VJ4+WjTbkf/A2FD5wuMIbO2FCTV39LE0w==
"@esbuild/freebsd-arm64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz#1f4af488bfc7e9ced04207034d398e793b570a27"
integrity sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==
"@esbuild/freebsd-arm64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.5.tgz#be1dd18b7b9411f10bdc362ba8bff16386175367"
integrity sha512-VbdXJkn2aI2pQ/wxNEjEcnEDwPpxt3CWWMFYmO7CcdFBoOsABRy2W8F3kjbF9F/pecEUDcI3b5i2w+By4VQFPg==
"@esbuild/freebsd-arm64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.7.tgz#1dd3de24a9683c8321a4e3c42b11b32a48e791d4"
integrity sha512-2NJjeQ9kiabJkVXLM3sHkySqkL1KY8BeyLams3ITyiLW10IwDL0msU5Lq1cULCn9zNxt1Seh1I6QrqyHUvOtQw==
"@esbuild/freebsd-x64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz#636306f19e9bc981e06aa1d777302dad8fddaf72"
integrity sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==
"@esbuild/freebsd-x64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.5.tgz#c9c1960fa3e1eada4e5d4be2a11a2f04ce14198f"
integrity sha512-olgGYND1/XnnWxwhjtY3/ryjOG/M4WfcA6XH8dBTH1cxMeBemMODXSFhkw71Kf4TeZFFTN25YOomaNh0vq2iXg==
"@esbuild/freebsd-x64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.7.tgz#b0e409e1c7cc05412c8dd149c2c39e0a1dee9567"
integrity sha512-8kSxlbjuLYMoIgvRxPybirHJeW45dflyIgHVs+jzMYJf87QOay1ZUTzKjNL3vqHQjmkSn8p6KDfHVrztn7Rprw==
"@esbuild/linux-arm64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz#a003f7ff237c501e095d4f3a09e58fc7b25a4aca"
integrity sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==
"@esbuild/linux-arm64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.5.tgz#34d96d11c6899017ecae42fb97de8e0c3282902f"
integrity sha512-8a0bqSwu3OlLCfu2FBbDNgQyBYdPJh1B9PvNX7jMaKGC9/KopgHs37t+pQqeMLzcyRqG6z55IGNQAMSlCpBuqg==
"@esbuild/linux-arm64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.7.tgz#35cfae28e460b96ccc027eccc28b13c0712d6df3"
integrity sha512-43Bbhq3Ia/mGFTCRA4NlY8VRH3dLQltJ4cqzhSfq+cdvdm9nKJXVh4NUkJvdZgEZIkf/ufeMmJ0/22v9btXTcw==
"@esbuild/linux-arm@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz#b591e6a59d9c4fe0eeadd4874b157ab78cf5f196"
integrity sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==
"@esbuild/linux-arm@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.5.tgz#86332e6293fd713a54ab299a5e2ed7c60c9e1c07"
integrity sha512-YBdCyQwA3OQupi6W2/WO4FnI+NWFWe79cZEtlbqSESOHEg7a73htBIRiE6uHPQe7Yp5E4aALv+JxkRLGEUL7tw==
"@esbuild/linux-arm@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.7.tgz#a378301c253ef64d19a112c9ec922680c2fb5a71"
integrity sha512-07RsAAzznWqdfJC+h3L2UVWwnUHepsFw5GmzySnUspHHb7glJ1+47rvlcH0SeUtoVOs8hF4/THgZbtJRyALaJA==
"@esbuild/linux-ia32@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz#24333a11027ef46a18f57019450a5188918e2a54"
integrity sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==
"@esbuild/linux-ia32@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.5.tgz#7bd9185c844e7dfce6a01dfdec584e115602a8c4"
integrity sha512-uCwm1r/+NdP7vndctgq3PoZrnmhmnecWAr114GWMRwg2QMFFX+kIWnp7IO220/JLgnXK/jP7VKAFBGmeOYBQYQ==
"@esbuild/linux-ia32@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.7.tgz#7d36087db95b1faaee8df203c511775a4d322a2b"
integrity sha512-ViYkfcfnbwOoTS7xE4DvYFv7QOlW8kPBuccc4erJ0jx2mXDPR7e0lYOH9JelotS9qe8uJ0s2i3UjUvjunEp53A==
"@esbuild/linux-loong64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz#d5ad459d41ed42bbd4d005256b31882ec52227d8"
integrity sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==
"@esbuild/linux-loong64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.5.tgz#2907d4120c7b3642b96be6014f77e7624c378eea"
integrity sha512-3YxhSBl5Sb6TtBjJu+HP93poBruFzgXmf3PVfIe4xOXMj1XpxboYZyw3W8BhoX/uwxzZz4K1I99jTE/5cgDT1g==
"@esbuild/linux-loong64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.7.tgz#b989253520308d81ee0e4846de9f63f2f11c7f10"
integrity sha512-H1g+AwwcqYQ/Hl/sMcopRcNLY/fysIb/ksDfCa3/kOaHQNhBrLeDYw+88VAFV5U6oJL9GqnmUj72m9Nv3th3hA==
"@esbuild/linux-mips64el@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz#4e5967a665c38360b0a8205594377d4dcf9c3726"
integrity sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==
"@esbuild/linux-mips64el@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.5.tgz#fc98be741e8080ecd13b404d5fca5302d3835bf4"
integrity sha512-Hy5Z0YVWyYHdtQ5mfmfp8LdhVwGbwVuq8mHzLqrG16BaMgEmit2xKO+iDakHs+OetEx0EN/2mUzDdfdktI+Nmg==
"@esbuild/linux-mips64el@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.7.tgz#ae751365cdf967dfa89dd59cdb0dcc8723a66f9a"
integrity sha512-MDLGrVbTGYtmldlbcxfeDPdhxttUmWoX3ovk9u6jc8iM+ueBAFlaXKuUMCoyP/zfOJb+KElB61eSdBPSvNcCEg==
"@esbuild/linux-ppc64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz#206443a02eb568f9fdf0b438fbd47d26e735afc8"
integrity sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==
"@esbuild/linux-ppc64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.5.tgz#ea12e8f6b290a613ac4903c9e00835c69ced065c"
integrity sha512-5dbQvBLbU/Y3Q4ABc9gi23hww1mQcM7KZ9KBqabB7qhJswYMf8WrDDOSw3gdf3p+ffmijMd28mfVMvFucuECyg==
"@esbuild/linux-ppc64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.7.tgz#ad1c9299c463f0409e57166e76e91afb6193ea9f"
integrity sha512-UWtLhRPKzI+v2bKk4j9rBpGyXbLAXLCOeqt1tLVAt1mfagHpFjUzzIHCpPiUfY3x1xY5e45/+BWzGpqqvSglNw==
"@esbuild/linux-riscv64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz#c351e433d009bf256e798ad048152c8d76da2fc9"
integrity sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==
"@esbuild/linux-riscv64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.5.tgz#ce47b15fd4227eeb0590826e41bdc430c5bfd06c"
integrity sha512-fp/KUB/ZPzEWGTEUgz9wIAKCqu7CjH1GqXUO2WJdik1UNBQ7Xzw7myIajpxztE4Csb9504ERiFMxZg5KZ6HlZQ==
"@esbuild/linux-riscv64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.7.tgz#84acb7451bef7458e6067d9c358026ffa1831910"
integrity sha512-3C/RTKqZauUwBYtIQAv7ELTJd+H2dNKPyzwE2ZTbz2RNrNhNHRoeKnG5C++eM6nSZWUCLyyaWfq1v1YRwBS/+A==
"@esbuild/linux-s390x@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz#661f271e5d59615b84b6801d1c2123ad13d9bd87"
integrity sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==
"@esbuild/linux-s390x@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.5.tgz#962fa540d7498967270eb1d4b9ac6c4a4f339735"
integrity sha512-kRV3yw19YDqHTp8SfHXfObUFXlaiiw4o2lvT1XjsPZ++22GqZwSsYWJLjMi1Sl7j9qDlDUduWDze/nQx0d6Lzw==
"@esbuild/linux-s390x@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.7.tgz#0bf23c78c52ea60ae4ea95239b728683a86a7ab8"
integrity sha512-x7cuRSCm998KFZqGEtSo8rI5hXLxWji4znZkBhg2FPF8A8lxLLCsSXe2P5utf0RBQflb3K97dkEH/BJwTqrbDw==
"@esbuild/linux-x64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz#e4ba18e8b149a89c982351443a377c723762b85f"
integrity sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==
"@esbuild/linux-x64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.5.tgz#9fa52884c3d876593a522aa1d4df43b717907050"
integrity sha512-vnxuhh9e4pbtABNLbT2ANW4uwQ/zvcHRCm1JxaYkzSehugoFd5iXyC4ci1nhXU13mxEwCnrnTIiiSGwa/uAF1g==
"@esbuild/linux-x64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.7.tgz#932d8c6e1b0d6a57a4e94a8390dfebeebba21dcc"
integrity sha512-1Z2BtWgM0Wc92WWiZR5kZ5eC+IetI++X+nf9NMbUvVymt74fnQqwgM5btlTW7P5uCHfq03u5MWHjIZa4o+TnXQ==
"@esbuild/netbsd-x64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz#7d4f4041e30c5c07dd24ffa295c73f06038ec775"
integrity sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==
"@esbuild/netbsd-x64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.5.tgz#47bb187b86aad9622051cb80c27e439b7d9e3a9a"
integrity sha512-cigBpdiSx/vPy7doUyImsQQBnBjV5f1M99ZUlaJckDAJjgXWl6y9W17FIfJTy8TxosEF6MXq+fpLsitMGts2nA==
"@esbuild/netbsd-x64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.7.tgz#6aa81873c6e08aa419378e07c8d3eed5aa77bf25"
integrity sha512-//VShPN4hgbmkDjYNCZermIhj8ORqoPNmAnwSPqPtBB0xOpHrXMlJhsqLNsgoBm0zi/5tmy//WyL6g81Uq2c6Q==
"@esbuild/openbsd-x64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz#970fa7f8470681f3e6b1db0cc421a4af8060ec35"
integrity sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==
"@esbuild/openbsd-x64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.5.tgz#abc55c35a1ed2bc3c5ede2ef50a3b2f87395009a"
integrity sha512-VdqRqPVIjjZfkf40LrqOaVuhw9EQiAZ/GNCSM2UplDkaIzYVsSnycxcFfAnHdWI8Gyt6dO15KHikbpxwx+xHbw==
"@esbuild/openbsd-x64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.7.tgz#0698f260250a7022e2cae7385cbd09a86eb0967c"
integrity sha512-IQ8BliXHiOsbQEOHzc7mVLIw2UYPpbOXJQ9cK1nClNYQjZthvfiA6rWZMz4BZpVzHZJ+/H2H23cZwRJ1NPYOGg==
"@esbuild/sunos-x64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz#abc60e7c4abf8b89fb7a4fe69a1484132238022c"
integrity sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==
"@esbuild/sunos-x64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.5.tgz#b83c080a2147662599a5d18b2ff47f07c93e03a0"
integrity sha512-ItxPaJ3MBLtI4nK+mALLEoUs6amxsx+J1ibnfcYMkqaCqHST1AkF4aENpBehty3czqw64r/XqL+W9WqU6kc2Qw==
"@esbuild/sunos-x64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.7.tgz#ef97445672deec50e3b3549af2ee6d42fbc04250"
integrity sha512-phO5HvU3SyURmcW6dfQXX4UEkFREUwaoiTgi1xH+CAFKPGsrcG6oDp1U70yQf5lxRKujoSCEIoBr0uFykJzN2g==
"@esbuild/win32-arm64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz#7b0ff9e8c3265537a7a7b1fd9a24e7bd39fcd87a"
integrity sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==
"@esbuild/win32-arm64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.5.tgz#2a4c41f427d9cf25b75f9d61493711a482106850"
integrity sha512-4u2Q6qsJTYNFdS9zHoAi80spzf78C16m2wla4eJPh4kSbRv+BpXIfl6TmBSWupD8e47B1NrTfrOlEuco7mYQtg==
"@esbuild/win32-arm64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.7.tgz#70865d2332d7883e2e49077770adfe51c51343e3"
integrity sha512-G/cRKlYrwp1B0uvzEdnFPJ3A6zSWjnsRrWivsEW0IEHZk+czv0Bmiwa51RncruHLjQ4fGsvlYPmCmwzmutPzHA==
"@esbuild/win32-ia32@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz#e90fe5267d71a7b7567afdc403dfd198c292eb09"
integrity sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==
"@esbuild/win32-ia32@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.5.tgz#7c14e3250725d0e2c21f89c98eb6abb520cba0e0"
integrity sha512-KYlm+Xu9TXsfTWAcocLuISRtqxKp/Y9ZBVg6CEEj0O5J9mn7YvBKzAszo2j1ndyzUPk+op+Tie2PJeN+BnXGqQ==
"@esbuild/win32-ia32@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.7.tgz#39831b787013c7da7e61c8eb6a9df0fed9bd0fcb"
integrity sha512-/yMNVlMew07NrOflJdRAZcMdUoYTOCPbCHx0eHtg55l87wXeuhvYOPBQy5HLX31Ku+W2XsBD5HnjUjEUsTXJug==
"@esbuild/win32-x64@0.16.17":
version "0.16.17"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz#c5a1a4bfe1b57f0c3e61b29883525c6da3e5c091"
integrity sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==
"@esbuild/win32-x64@0.17.5":
version "0.17.5"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.5.tgz#a8f3d26d8afc5186eccda265ceb1820b8e8830be"
integrity sha512-XgA9qWRqby7xdYXuF6KALsn37QGBMHsdhmnpjfZtYxKxbTOwfnDM6MYi2WuUku5poNaX2n9XGVr20zgT/2QwCw==
"@esbuild/win32-x64@0.17.7":
version "0.17.7"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.7.tgz#03b231fcfa0702562978979468dfc8b09b55ac59"
integrity sha512-K9/YybM6WZO71x73Iyab6mwieHtHjm9hrPR/a9FBPZmFO3w+fJaM2uu2rt3JYf/rZR24MFwTliI8VSoKKOtYtg==
"@eslint/eslintrc@^1.4.1":
version "1.4.1"
@@ -2736,14 +2736,14 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@^5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.50.0.tgz#fb48c31cadc853ffc1dc35373f56b5e2a8908fe9"
integrity sha512-vwksQWSFZiUhgq3Kv7o1Jcj0DUNylwnIlGvKvLLYsq8pAWha6/WCnXUeaSoNNha/K7QSf2+jvmkxggC1u3pIwQ==
"@typescript-eslint/eslint-plugin@^5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.51.0.tgz#da3f2819633061ced84bb82c53bba45a6fe9963a"
integrity sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==
dependencies:
"@typescript-eslint/scope-manager" "5.50.0"
"@typescript-eslint/type-utils" "5.50.0"
"@typescript-eslint/utils" "5.50.0"
"@typescript-eslint/scope-manager" "5.51.0"
"@typescript-eslint/type-utils" "5.51.0"
"@typescript-eslint/utils" "5.51.0"
debug "^4.3.4"
grapheme-splitter "^1.0.4"
ignore "^5.2.0"
@@ -2752,72 +2752,72 @@
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/parser@^5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.50.0.tgz#a33f44b2cc83d1b7176ec854fbecd55605b0b032"
integrity sha512-KCcSyNaogUDftK2G9RXfQyOCt51uB5yqC6pkUYqhYh8Kgt+DwR5M0EwEAxGPy/+DH6hnmKeGsNhiZRQxjH71uQ==
"@typescript-eslint/parser@^5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.51.0.tgz#2d74626652096d966ef107f44b9479f02f51f271"
integrity sha512-fEV0R9gGmfpDeRzJXn+fGQKcl0inIeYobmmUWijZh9zA7bxJ8clPhV9up2ZQzATxAiFAECqPQyMDB4o4B81AaA==
dependencies:
"@typescript-eslint/scope-manager" "5.50.0"
"@typescript-eslint/types" "5.50.0"
"@typescript-eslint/typescript-estree" "5.50.0"
"@typescript-eslint/scope-manager" "5.51.0"
"@typescript-eslint/types" "5.51.0"
"@typescript-eslint/typescript-estree" "5.51.0"
debug "^4.3.4"
"@typescript-eslint/scope-manager@5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.50.0.tgz#90b8a3b337ad2c52bbfe4eac38f9164614e40584"
integrity sha512-rt03kaX+iZrhssaT974BCmoUikYtZI24Vp/kwTSy841XhiYShlqoshRFDvN1FKKvU2S3gK+kcBW1EA7kNUrogg==
"@typescript-eslint/scope-manager@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.51.0.tgz#ad3e3c2ecf762d9a4196c0fbfe19b142ac498990"
integrity sha512-gNpxRdlx5qw3yaHA0SFuTjW4rxeYhpHxt491PEcKF8Z6zpq0kMhe0Tolxt0qjlojS+/wArSDlj/LtE69xUJphQ==
dependencies:
"@typescript-eslint/types" "5.50.0"
"@typescript-eslint/visitor-keys" "5.50.0"
"@typescript-eslint/types" "5.51.0"
"@typescript-eslint/visitor-keys" "5.51.0"
"@typescript-eslint/type-utils@5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.50.0.tgz#509d5cc9728d520008f7157b116a42c5460e7341"
integrity sha512-dcnXfZ6OGrNCO7E5UY/i0ktHb7Yx1fV6fnQGGrlnfDhilcs6n19eIRcvLBqx6OQkrPaFlDPk3OJ0WlzQfrV0bQ==
"@typescript-eslint/type-utils@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.51.0.tgz#7af48005531700b62a20963501d47dfb27095988"
integrity sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==
dependencies:
"@typescript-eslint/typescript-estree" "5.50.0"
"@typescript-eslint/utils" "5.50.0"
"@typescript-eslint/typescript-estree" "5.51.0"
"@typescript-eslint/utils" "5.51.0"
debug "^4.3.4"
tsutils "^3.21.0"
"@typescript-eslint/types@5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.50.0.tgz#c461d3671a6bec6c2f41f38ed60bd87aa8a30093"
integrity sha512-atruOuJpir4OtyNdKahiHZobPKFvZnBnfDiyEaBf6d9vy9visE7gDjlmhl+y29uxZ2ZDgvXijcungGFjGGex7w==
"@typescript-eslint/types@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.51.0.tgz#e7c1622f46c7eea7e12bbf1edfb496d4dec37c90"
integrity sha512-SqOn0ANn/v6hFn0kjvLwiDi4AzR++CBZz0NV5AnusT2/3y32jdc0G4woXPWHCumWtUXZKPAS27/9vziSsC9jnw==
"@typescript-eslint/typescript-estree@5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.50.0.tgz#0b9b82975bdfa40db9a81fdabc7f93396867ea97"
integrity sha512-Gq4zapso+OtIZlv8YNAStFtT6d05zyVCK7Fx3h5inlLBx2hWuc/0465C2mg/EQDDU2LKe52+/jN4f0g9bd+kow==
"@typescript-eslint/typescript-estree@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.51.0.tgz#0ec8170d7247a892c2b21845b06c11eb0718f8de"
integrity sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==
dependencies:
"@typescript-eslint/types" "5.50.0"
"@typescript-eslint/visitor-keys" "5.50.0"
"@typescript-eslint/types" "5.51.0"
"@typescript-eslint/visitor-keys" "5.51.0"
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.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.50.0.tgz#807105f5ffb860644d30d201eefad7017b020816"
integrity sha512-v/AnUFImmh8G4PH0NDkf6wA8hujNNcrwtecqW4vtQ1UOSNBaZl49zP1SHoZ/06e+UiwzHpgb5zP5+hwlYYWYAw==
"@typescript-eslint/utils@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.51.0.tgz#074f4fabd5b12afe9c8aa6fdee881c050f8b4d47"
integrity sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==
dependencies:
"@types/json-schema" "^7.0.9"
"@types/semver" "^7.3.12"
"@typescript-eslint/scope-manager" "5.50.0"
"@typescript-eslint/types" "5.50.0"
"@typescript-eslint/typescript-estree" "5.50.0"
"@typescript-eslint/scope-manager" "5.51.0"
"@typescript-eslint/types" "5.51.0"
"@typescript-eslint/typescript-estree" "5.51.0"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
semver "^7.3.7"
"@typescript-eslint/visitor-keys@5.50.0":
version "5.50.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.50.0.tgz#b752ffc143841f3d7bc57d6dd01ac5c40f8c4903"
integrity sha512-cdMeD9HGu6EXIeGOh2yVW6oGf9wq8asBgZx7nsR/D36gTfQ0odE5kcRYe5M81vjEFAcPeugXrHg78Imu55F6gg==
"@typescript-eslint/visitor-keys@5.51.0":
version "5.51.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.51.0.tgz#c0147dd9a36c0de758aaebd5b48cae1ec59eba87"
integrity sha512-Oh2+eTdjHjOFjKA27sxESlA87YPSOJafGCR0md5oeMdh1ZcCfAGCIOL216uTBAkAIptvLIfKQhl7lHxMJet4GQ==
dependencies:
"@typescript-eslint/types" "5.50.0"
"@typescript-eslint/types" "5.51.0"
eslint-visitor-keys "^3.3.0"
"@webassemblyjs/ast@1.11.1":
@@ -5358,33 +5358,33 @@ esbuild@^0.16.17:
"@esbuild/win32-ia32" "0.16.17"
"@esbuild/win32-x64" "0.16.17"
esbuild@^0.17.5:
version "0.17.5"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.5.tgz#cd76d75700d49ac050ad9eedfbed777bd6a9d930"
integrity sha512-Bu6WLCc9NMsNoMJUjGl3yBzTjVLXdysMltxQWiLAypP+/vQrf+3L1Xe8fCXzxaECus2cEJ9M7pk4yKatEwQMqQ==
esbuild@^0.17.7:
version "0.17.7"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.7.tgz#a7ace55f2bf82fdb1c9013a924620ce2596984fa"
integrity sha512-+5hHlrK108fT6C6/40juy0w4DYKtyZ5NjfBlTccBdsFutR7WBxpIY633JzZJewdsCy8xWA/u2z0MSniIJwufYg==
optionalDependencies:
"@esbuild/android-arm" "0.17.5"
"@esbuild/android-arm64" "0.17.5"
"@esbuild/android-x64" "0.17.5"
"@esbuild/darwin-arm64" "0.17.5"
"@esbuild/darwin-x64" "0.17.5"
"@esbuild/freebsd-arm64" "0.17.5"
"@esbuild/freebsd-x64" "0.17.5"
"@esbuild/linux-arm" "0.17.5"
"@esbuild/linux-arm64" "0.17.5"
"@esbuild/linux-ia32" "0.17.5"
"@esbuild/linux-loong64" "0.17.5"
"@esbuild/linux-mips64el" "0.17.5"
"@esbuild/linux-ppc64" "0.17.5"
"@esbuild/linux-riscv64" "0.17.5"
"@esbuild/linux-s390x" "0.17.5"
"@esbuild/linux-x64" "0.17.5"
"@esbuild/netbsd-x64" "0.17.5"
"@esbuild/openbsd-x64" "0.17.5"
"@esbuild/sunos-x64" "0.17.5"
"@esbuild/win32-arm64" "0.17.5"
"@esbuild/win32-ia32" "0.17.5"
"@esbuild/win32-x64" "0.17.5"
"@esbuild/android-arm" "0.17.7"
"@esbuild/android-arm64" "0.17.7"
"@esbuild/android-x64" "0.17.7"
"@esbuild/darwin-arm64" "0.17.7"
"@esbuild/darwin-x64" "0.17.7"
"@esbuild/freebsd-arm64" "0.17.7"
"@esbuild/freebsd-x64" "0.17.7"
"@esbuild/linux-arm" "0.17.7"
"@esbuild/linux-arm64" "0.17.7"
"@esbuild/linux-ia32" "0.17.7"
"@esbuild/linux-loong64" "0.17.7"
"@esbuild/linux-mips64el" "0.17.7"
"@esbuild/linux-ppc64" "0.17.7"
"@esbuild/linux-riscv64" "0.17.7"
"@esbuild/linux-s390x" "0.17.7"
"@esbuild/linux-x64" "0.17.7"
"@esbuild/netbsd-x64" "0.17.7"
"@esbuild/openbsd-x64" "0.17.7"
"@esbuild/sunos-x64" "0.17.7"
"@esbuild/win32-arm64" "0.17.7"
"@esbuild/win32-ia32" "0.17.7"
"@esbuild/win32-x64" "0.17.7"
escalade@^3.1.1:
version "3.1.1"