mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add enough code to get first couple terminal tests to pass
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
87dc14cbfb
commit
dba4f59644
@ -118,8 +118,7 @@
|
||||
"<rootDir>/packages"
|
||||
],
|
||||
"setupFiles": [
|
||||
"<rootDir>/src/jest.setup.ts",
|
||||
"jest-canvas-mock"
|
||||
"<rootDir>/src/jest.setup.ts"
|
||||
],
|
||||
"globalSetup": "<rootDir>/src/jest.timezone.ts",
|
||||
"setupFilesAfterEnv": [
|
||||
@ -265,7 +264,7 @@
|
||||
"immer": "^9.0.17",
|
||||
"joi": "^17.7.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jsdom": "^16.7.0",
|
||||
"jsdom": "^20.0.1",
|
||||
"lodash": "^4.17.15",
|
||||
"marked": "^4.2.5",
|
||||
"md5-file": "^5.0.0",
|
||||
@ -335,6 +334,7 @@
|
||||
"@types/html-webpack-plugin": "^3.2.6",
|
||||
"@types/http-proxy": "^1.17.9",
|
||||
"@types/jest": "^28.1.6",
|
||||
"@types/jest-image-snapshot": "^5.1.0",
|
||||
"@types/js-yaml": "^4.0.5",
|
||||
"@types/jsdom": "^16.2.14",
|
||||
"@types/lodash": "^4.14.191",
|
||||
@ -375,6 +375,7 @@
|
||||
"adr": "^1.4.3",
|
||||
"ansi_up": "^5.1.0",
|
||||
"chalk": "^4.1.2",
|
||||
"canvas": "^2.10.1",
|
||||
"chart.js": "^2.9.4",
|
||||
"circular-dependency-plugin": "^5.2.2",
|
||||
"cli-progress": "^3.11.2",
|
||||
@ -403,8 +404,8 @@
|
||||
"ignore-loader": "^0.1.2",
|
||||
"include-media": "^1.4.9",
|
||||
"jest": "^28.1.3",
|
||||
"jest-canvas-mock": "^2.3.1",
|
||||
"jest-environment-jsdom": "^28.1.3",
|
||||
"jest-image-snapshot": "^5.2.0",
|
||||
"jest-mock-extended": "^2.0.9",
|
||||
"make-plural": "^6.2.2",
|
||||
"memfs": "^3.4.12",
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { AppPaths } from "./app-path-injection-token";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel";
|
||||
|
||||
export type AppPathsChannel = RequestChannel<void, AppPaths>;
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*/
|
||||
import type { HelmRepo } from "./helm-repo";
|
||||
import type { AsyncResult } from "../utils/async-result";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel";
|
||||
|
||||
export type AddHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<void, string>>;
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
*/
|
||||
import type { HelmRepo } from "./helm-repo";
|
||||
import type { AsyncResult } from "../utils/async-result";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel";
|
||||
|
||||
export type GetActiveHelmRepositoriesChannel = RequestChannel<void, AsyncResult<HelmRepo[]>>;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { AsyncResult } from "../utils/async-result";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../utils/channel/request-channel";
|
||||
import type { HelmRepo } from "./helm-repo";
|
||||
|
||||
export type RemoveHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<void, string>>;
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
|
||||
|
||||
export interface Logger {
|
||||
info: (message: string, ...args: any) => void;
|
||||
error: (message: string, ...args: any) => void;
|
||||
debug: (message: string, ...args: any) => void;
|
||||
warn: (message: string, ...args: any) => void;
|
||||
silly: (message: string, ...args: any) => void;
|
||||
info: (message: string, ...args: any[]) => void;
|
||||
error: (message: string, ...args: any[]) => void;
|
||||
debug: (message: string, ...args: any[]) => void;
|
||||
warn: (message: string, ...args: any[]) => void;
|
||||
silly: (message: string, ...args: any[]) => void;
|
||||
}
|
||||
|
||||
@ -11,15 +11,15 @@ import { getApplicationBuilder } from "../../../renderer/components/test-utils/g
|
||||
import type { LensWindow } from "../../../main/start-main-application/lens-window/application-window/create-lens-window.injectable";
|
||||
import type { MessageChannel } from "./message-channel-listener-injection-token";
|
||||
import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token";
|
||||
import type { RequestFromChannel } from "./request-from-channel-injection-token";
|
||||
import { requestFromChannelInjectionToken } from "./request-from-channel-injection-token";
|
||||
import type { RequestChannel } from "./request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "./request-channel";
|
||||
import type { AsyncFnMock } from "@async-fn/jest";
|
||||
import asyncFn from "@async-fn/jest";
|
||||
import { getPromiseStatus } from "../../test-utils/get-promise-status";
|
||||
import { runInAction } from "mobx";
|
||||
import type { RequestChannelHandler } from "../../../main/utils/channel/channel-listeners/listener-tokens";
|
||||
import { getRequestChannelListenerInjectable } from "../../../main/utils/channel/channel-listeners/listener-tokens";
|
||||
import type { RequestFromChannel } from "../../../renderer/utils/channel/request-from-channel.injectable";
|
||||
import requestFromChannelInjectable from "../../../renderer/utils/channel/request-from-channel.injectable";
|
||||
|
||||
type TestMessageChannel = MessageChannel<string>;
|
||||
type TestRequestChannel = RequestChannel<string, string>;
|
||||
@ -164,9 +164,7 @@ describe("channel", () => {
|
||||
|
||||
const windowDi = applicationBuilder.applicationWindow.only.di;
|
||||
|
||||
requestFromChannel = windowDi.inject(
|
||||
requestFromChannelInjectionToken,
|
||||
);
|
||||
requestFromChannel = windowDi.inject(requestFromChannelInjectable);
|
||||
});
|
||||
|
||||
describe("when requesting from channel", () => {
|
||||
|
||||
@ -8,3 +8,11 @@ export interface RequestChannel<Request, Response> {
|
||||
_requestSignature?: Request; // used only to mark `Request` as "used"
|
||||
_responseSignature?: Response; // used only to mark `Response` as "used"
|
||||
}
|
||||
|
||||
export type ChannelRequest<Channel> = Channel extends RequestChannel<infer Request, any>
|
||||
? Request
|
||||
: never;
|
||||
|
||||
export type ChannelResponse<Channel> = Channel extends RequestChannel<any, infer Response>
|
||||
? Response
|
||||
: never;
|
||||
@ -1,15 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||
import type { RequestChannel } from "./request-channel-listener-injection-token";
|
||||
|
||||
export interface RequestFromChannel {
|
||||
<Request, Response>(channel: RequestChannel<Request, Response>, request: Request): Promise<Response>;
|
||||
<Response>(channel: RequestChannel<void, Response>): Promise<Response>;
|
||||
}
|
||||
|
||||
export const requestFromChannelInjectionToken = getInjectionToken<RequestFromChannel>({
|
||||
id: "request-from-request-channel",
|
||||
});
|
||||
@ -2,7 +2,7 @@
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { RequestChannel } from "../channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../channel/request-channel";
|
||||
|
||||
export type ResolveSystemProxyChannel = RequestChannel<string, string>;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { MessageChannel } from "../channel/message-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../channel/request-channel";
|
||||
|
||||
export type SyncBoxChannel = MessageChannel<{ id: string; value: any }>;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { ClusterId } from "../../../../common/cluster-types";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel";
|
||||
|
||||
export type ClearClusterAsDeletingChannel = RequestChannel<ClusterId, void>;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { ClusterId } from "../../../../common/cluster-types";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel";
|
||||
|
||||
export type DeleteClusterChannel = RequestChannel<ClusterId, void>;
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import type { ClusterId } from "../../../../common/cluster-types";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel";
|
||||
|
||||
export type SetClusterAsDeletingChannel = RequestChannel<ClusterId, void>;
|
||||
|
||||
|
||||
@ -5,16 +5,16 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { asyncComputed } from "@ogre-tools/injectable-react";
|
||||
import { getActiveHelmRepositoriesChannel } from "../../../../../common/helm/get-active-helm-repositories-channel";
|
||||
import { requestFromChannelInjectionToken } from "../../../../../common/utils/channel/request-from-channel-injection-token";
|
||||
import showErrorNotificationInjectable from "../../../../../renderer/components/notifications/show-error-notification.injectable";
|
||||
import helmRepositoriesErrorStateInjectable from "./helm-repositories-error-state.injectable";
|
||||
import { runInAction } from "mobx";
|
||||
import requestFromChannelInjectable from "../../../../../renderer/utils/channel/request-from-channel.injectable";
|
||||
|
||||
const activeHelmRepositoriesInjectable = getInjectable({
|
||||
id: "active-helm-repositories",
|
||||
|
||||
instantiate: (di) => {
|
||||
const requestFromChannel = di.inject(requestFromChannelInjectionToken);
|
||||
const requestFromChannel = di.inject(requestFromChannelInjectable);
|
||||
const showErrorNotification = di.inject(showErrorNotificationInjectable);
|
||||
const helmRepositoriesErrorState = di.inject(
|
||||
helmRepositoriesErrorStateInjectable,
|
||||
|
||||
@ -4,17 +4,17 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { HelmRepo } from "../../../../../../../common/helm/helm-repo";
|
||||
import { requestFromChannelInjectionToken } from "../../../../../../../common/utils/channel/request-from-channel-injection-token";
|
||||
import activeHelmRepositoriesInjectable from "../../active-helm-repositories.injectable";
|
||||
import showErrorNotificationInjectable from "../../../../../../../renderer/components/notifications/show-error-notification.injectable";
|
||||
import showSuccessNotificationInjectable from "../../../../../../../renderer/components/notifications/show-success-notification.injectable";
|
||||
import { addHelmRepositoryChannel } from "../../../../../../../common/helm/add-helm-repository-channel";
|
||||
import requestFromChannelInjectable from "../../../../../../utils/channel/request-from-channel.injectable";
|
||||
|
||||
const addHelmRepositoryInjectable = getInjectable({
|
||||
id: "add-public-helm-repository",
|
||||
|
||||
instantiate: (di) => {
|
||||
const requestFromChannel = di.inject(requestFromChannelInjectionToken);
|
||||
const requestFromChannel = di.inject(requestFromChannelInjectable);
|
||||
const activeHelmRepositories = di.inject(activeHelmRepositoriesInjectable);
|
||||
const showErrorNotification = di.inject(showErrorNotificationInjectable);
|
||||
const showSuccessNotification = di.inject(showSuccessNotificationInjectable);
|
||||
|
||||
@ -4,15 +4,15 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { HelmRepo } from "../../../../../common/helm/helm-repo";
|
||||
import { requestFromChannelInjectionToken } from "../../../../../common/utils/channel/request-from-channel-injection-token";
|
||||
import activeHelmRepositoriesInjectable from "./active-helm-repositories.injectable";
|
||||
import { removeHelmRepositoryChannel } from "../../../../../common/helm/remove-helm-repository-channel";
|
||||
import requestFromChannelInjectable from "../../../../utils/channel/request-from-channel.injectable";
|
||||
|
||||
const removePublicHelmRepositoryInjectable = getInjectable({
|
||||
id: "remove-public-helm-repository",
|
||||
|
||||
instantiate: (di) => {
|
||||
const requestFromChannel = di.inject(requestFromChannelInjectionToken);
|
||||
const requestFromChannel = di.inject(requestFromChannelInjectable);
|
||||
const activeHelmRepositories = di.inject(activeHelmRepositoriesInjectable);
|
||||
|
||||
return async (repository: HelmRepo) => {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 593 B |
@ -0,0 +1,584 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`test for opening terminal tab within cluster frame when new terminal tab is opened renders 1`] = `
|
||||
<body>
|
||||
<div>
|
||||
<div
|
||||
id="terminal-init"
|
||||
/>
|
||||
<div
|
||||
class="Notifications flex column align-flex-end"
|
||||
/>
|
||||
<div
|
||||
class="mainLayout"
|
||||
style="--sidebar-width: 200px;"
|
||||
>
|
||||
<div
|
||||
class="sidebar"
|
||||
>
|
||||
<div
|
||||
class="flex flex-col"
|
||||
data-testid="cluster-sidebar"
|
||||
>
|
||||
<div
|
||||
class="SidebarCluster"
|
||||
>
|
||||
<div
|
||||
class="Avatar rounded loadingAvatar"
|
||||
style="width: 40px; height: 40px;"
|
||||
>
|
||||
??
|
||||
</div>
|
||||
<div
|
||||
class="loadingClusterName"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="sidebarNav sidebar-active-status"
|
||||
>
|
||||
<div
|
||||
class="SidebarItem"
|
||||
data-is-active-test="true"
|
||||
data-testid="sidebar-item-workloads"
|
||||
>
|
||||
<a
|
||||
aria-current="page"
|
||||
class="navItem active"
|
||||
data-testid="sidebar-item-link-for-workloads"
|
||||
href="/"
|
||||
>
|
||||
<i
|
||||
class="Icon svg focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
/>
|
||||
</i>
|
||||
<span>
|
||||
Workloads
|
||||
</span>
|
||||
<i
|
||||
class="Icon expandIcon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="keyboard_arrow_down"
|
||||
>
|
||||
keyboard_arrow_down
|
||||
</span>
|
||||
</i>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="SidebarItem"
|
||||
data-is-active-test="false"
|
||||
data-testid="sidebar-item-config"
|
||||
>
|
||||
<a
|
||||
class="navItem"
|
||||
data-testid="sidebar-item-link-for-config"
|
||||
href="/"
|
||||
>
|
||||
<i
|
||||
class="Icon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="list"
|
||||
>
|
||||
list
|
||||
</span>
|
||||
</i>
|
||||
<span>
|
||||
Config
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="SidebarItem"
|
||||
data-is-active-test="false"
|
||||
data-testid="sidebar-item-network"
|
||||
>
|
||||
<a
|
||||
class="navItem"
|
||||
data-testid="sidebar-item-link-for-network"
|
||||
href="/"
|
||||
>
|
||||
<i
|
||||
class="Icon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="device_hub"
|
||||
>
|
||||
device_hub
|
||||
</span>
|
||||
</i>
|
||||
<span>
|
||||
Network
|
||||
</span>
|
||||
<i
|
||||
class="Icon expandIcon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="keyboard_arrow_down"
|
||||
>
|
||||
keyboard_arrow_down
|
||||
</span>
|
||||
</i>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="SidebarItem"
|
||||
data-is-active-test="false"
|
||||
data-testid="sidebar-item-storage"
|
||||
>
|
||||
<a
|
||||
class="navItem"
|
||||
data-testid="sidebar-item-link-for-storage"
|
||||
href="/"
|
||||
>
|
||||
<i
|
||||
class="Icon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="storage"
|
||||
>
|
||||
storage
|
||||
</span>
|
||||
</i>
|
||||
<span>
|
||||
Storage
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="SidebarItem"
|
||||
data-is-active-test="false"
|
||||
data-testid="sidebar-item-helm"
|
||||
>
|
||||
<a
|
||||
class="navItem"
|
||||
data-testid="sidebar-item-link-for-helm"
|
||||
href="/"
|
||||
>
|
||||
<i
|
||||
class="Icon svg focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
/>
|
||||
</i>
|
||||
<span>
|
||||
Helm
|
||||
</span>
|
||||
<i
|
||||
class="Icon expandIcon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="keyboard_arrow_down"
|
||||
>
|
||||
keyboard_arrow_down
|
||||
</span>
|
||||
</i>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="SidebarItem"
|
||||
data-is-active-test="false"
|
||||
data-testid="sidebar-item-user-management"
|
||||
>
|
||||
<a
|
||||
class="navItem"
|
||||
data-testid="sidebar-item-link-for-user-management"
|
||||
href="/"
|
||||
>
|
||||
<i
|
||||
class="Icon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="security"
|
||||
>
|
||||
security
|
||||
</span>
|
||||
</i>
|
||||
<span>
|
||||
Access Control
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="SidebarItem"
|
||||
data-is-active-test="false"
|
||||
data-testid="sidebar-item-custom-resources"
|
||||
>
|
||||
<a
|
||||
class="navItem"
|
||||
data-testid="sidebar-item-link-for-custom-resources"
|
||||
href="/"
|
||||
>
|
||||
<i
|
||||
class="Icon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="extension"
|
||||
>
|
||||
extension
|
||||
</span>
|
||||
</i>
|
||||
<span>
|
||||
Custom Resources
|
||||
</span>
|
||||
<i
|
||||
class="Icon expandIcon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="keyboard_arrow_down"
|
||||
>
|
||||
keyboard_arrow_down
|
||||
</span>
|
||||
</i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ResizingAnchor horizontal trailing"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="contents"
|
||||
>
|
||||
<div
|
||||
class="TabLayout"
|
||||
data-testid="tab-layout"
|
||||
>
|
||||
<div
|
||||
class="Tabs center scrollable"
|
||||
>
|
||||
<div
|
||||
class="Tab flex gaps align-center active"
|
||||
data-is-active-test="true"
|
||||
data-testid="tab-link-for-overview"
|
||||
role="tab"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="label"
|
||||
>
|
||||
Overview
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<main>
|
||||
<div
|
||||
class="WorkloadsOverview flex column gaps"
|
||||
data-testid="page-for-workloads-overview"
|
||||
>
|
||||
<div
|
||||
class="header flex gaps align-center"
|
||||
>
|
||||
<h5
|
||||
class="box grow"
|
||||
>
|
||||
Overview
|
||||
</h5>
|
||||
<div
|
||||
class="NamespaceSelectFilterParent"
|
||||
data-testid="namespace-select-filter"
|
||||
>
|
||||
<div
|
||||
class="Select theme-dark NamespaceSelect NamespaceSelectFilter css-b62m3t-container"
|
||||
>
|
||||
<span
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
id="react-select-overview-namespace-select-filter-input-live-region"
|
||||
/>
|
||||
<span
|
||||
aria-atomic="false"
|
||||
aria-live="polite"
|
||||
aria-relevant="additions text"
|
||||
class="css-1f43avz-a11yText-A11yText"
|
||||
/>
|
||||
<div
|
||||
class="Select__control css-1s2u09g-control"
|
||||
>
|
||||
<div
|
||||
class="Select__value-container Select__value-container--is-multi css-319lph-ValueContainer"
|
||||
>
|
||||
<div
|
||||
class="Select__placeholder css-14el2xx-placeholder"
|
||||
id="react-select-overview-namespace-select-filter-input-placeholder"
|
||||
>
|
||||
All namespaces
|
||||
</div>
|
||||
<div
|
||||
class="Select__input-container css-6j8wv5-Input"
|
||||
data-value=""
|
||||
>
|
||||
<input
|
||||
aria-autocomplete="list"
|
||||
aria-describedby="react-select-overview-namespace-select-filter-input-placeholder"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="true"
|
||||
autocapitalize="none"
|
||||
autocomplete="off"
|
||||
autocorrect="off"
|
||||
class="Select__input"
|
||||
id="overview-namespace-select-filter-input"
|
||||
role="combobox"
|
||||
spellcheck="false"
|
||||
style="opacity: 1; width: 100%; grid-area: 1 / 2; min-width: 2px; border: 0px; margin: 0px; outline: 0; padding: 0px;"
|
||||
tabindex="0"
|
||||
type="text"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="Select__indicators css-1hb7zxy-IndicatorsContainer"
|
||||
>
|
||||
<span
|
||||
class="Select__indicator-separator css-1okebmr-indicatorSeparator"
|
||||
/>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="Select__indicator Select__dropdown-indicator css-tlfecz-indicatorContainer"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="css-tj5bde-Svg"
|
||||
focusable="false"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
width="20"
|
||||
>
|
||||
<path
|
||||
d="M4.516 7.548c0.436-0.446 1.043-0.481 1.576 0l3.908 3.747 3.908-3.747c0.533-0.481 1.141-0.446 1.574 0 0.436 0.445 0.408 1.197 0 1.615-0.406 0.418-4.695 4.502-4.695 4.502-0.217 0.223-0.502 0.335-0.787 0.335s-0.57-0.112-0.789-0.335c0 0-4.287-4.084-4.695-4.502s-0.436-1.17 0-1.615z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="OverviewStatuses"
|
||||
>
|
||||
<div
|
||||
class="workloads"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="footer"
|
||||
>
|
||||
<div
|
||||
class="Dock isOpen"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="ResizingAnchor vertical leading"
|
||||
/>
|
||||
<div
|
||||
class="tabs-container flex align-center"
|
||||
>
|
||||
<div
|
||||
class="dockTabs"
|
||||
role="tablist"
|
||||
>
|
||||
<div
|
||||
class="Tabs tabs"
|
||||
>
|
||||
<div
|
||||
class="Tab flex gaps align-center DockTab TerminalTab active"
|
||||
data-testid="dock-tab-for-terminal"
|
||||
id="tab-terminal"
|
||||
role="tab"
|
||||
tabindex="0"
|
||||
>
|
||||
<i
|
||||
class="Icon material focusable"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="terminal"
|
||||
>
|
||||
terminal
|
||||
</span>
|
||||
</i>
|
||||
<div
|
||||
class="label"
|
||||
>
|
||||
<div
|
||||
class="flex align-center"
|
||||
>
|
||||
<span
|
||||
class="title"
|
||||
>
|
||||
Terminal
|
||||
</span>
|
||||
<div
|
||||
class="close"
|
||||
>
|
||||
<i
|
||||
class="Icon material interactive focusable small"
|
||||
data-testid="dock-tab-close-for-terminal"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="close"
|
||||
>
|
||||
close
|
||||
</span>
|
||||
</i>
|
||||
<div
|
||||
data-testid="tooltip-content-for-dock-tab-close-for-terminal"
|
||||
>
|
||||
Close ⌘+W
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="toolbar flex gaps align-center box grow"
|
||||
>
|
||||
<div
|
||||
class="dock-menu box grow"
|
||||
>
|
||||
<i
|
||||
class="Icon new-dock-tab material interactive focusable"
|
||||
id="menu-actions-for-dock"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
class="icon"
|
||||
data-icon-name="add"
|
||||
>
|
||||
add
|
||||
</span>
|
||||
</i>
|
||||
<div>
|
||||
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 terminal"
|
||||
data-testid="dock-tab-content-for-terminal"
|
||||
style="flex-basis: 300px;"
|
||||
>
|
||||
<div
|
||||
class="TerminalWindow dark"
|
||||
>
|
||||
<div
|
||||
class="terminal xterm"
|
||||
dir="ltr"
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
class="xterm-viewport"
|
||||
style="background-color: rgb(0, 0, 0);"
|
||||
>
|
||||
<div
|
||||
class="xterm-scroll-area"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="xterm-screen"
|
||||
>
|
||||
<div
|
||||
class="xterm-helpers"
|
||||
>
|
||||
<textarea
|
||||
aria-label="Terminal input"
|
||||
aria-multiline="false"
|
||||
autocapitalize="off"
|
||||
autocorrect="off"
|
||||
class="xterm-helper-textarea"
|
||||
spellcheck="false"
|
||||
tabindex="0"
|
||||
/>
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="xterm-char-measure-element"
|
||||
style="font-size: 42px;"
|
||||
>
|
||||
W
|
||||
</span>
|
||||
<div
|
||||
class="composition-view"
|
||||
/>
|
||||
</div>
|
||||
<canvas
|
||||
class="xterm-text-layer"
|
||||
style="z-index: 0;"
|
||||
/>
|
||||
<canvas
|
||||
class="xterm-selection-layer"
|
||||
style="z-index: 1;"
|
||||
/>
|
||||
<canvas
|
||||
class="xterm-link-layer"
|
||||
style="z-index: 2;"
|
||||
/>
|
||||
<canvas
|
||||
class="xterm-cursor-layer"
|
||||
style="z-index: 3;"
|
||||
/>
|
||||
<div
|
||||
class="xterm-decoration-container"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
`;
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RequestChannel } from "../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../../../common/utils/channel/request-channel";
|
||||
|
||||
export interface ShellApiAuthArgs {
|
||||
clusterId: string;
|
||||
|
||||
63
src/features/terminal/opening-terminal-tab.test.tsx
Normal file
63
src/features/terminal/opening-terminal-tab.test.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import type { RenderResult } from "@testing-library/react";
|
||||
import assert from "assert";
|
||||
import { TypedRegEx } from "typed-regex";
|
||||
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||
|
||||
const pngBase64Matcher = TypedRegEx("data:image/png;base64,(?<ENCODED>.+)");
|
||||
|
||||
function convertCanvasToPngBuffer(canvas: { toDataURL: () => string }): Buffer {
|
||||
const content = canvas.toDataURL();
|
||||
const match = pngBase64Matcher.captures(content);
|
||||
|
||||
assert(match);
|
||||
|
||||
return Buffer.from(match.ENCODED, "base64");
|
||||
}
|
||||
|
||||
describe("test for opening terminal tab within cluster frame", () => {
|
||||
let builder: ApplicationBuilder;
|
||||
let result: RenderResult;
|
||||
let textCanvas: HTMLCanvasElement;
|
||||
|
||||
beforeEach(async () => {
|
||||
builder = getApplicationBuilder();
|
||||
builder.setEnvironmentToClusterFrame();
|
||||
|
||||
result = await builder.render();
|
||||
});
|
||||
|
||||
describe("when new terminal tab is opened", () => {
|
||||
beforeEach(() => {
|
||||
result.getByTestId("dock-tab-for-terminal").click();
|
||||
textCanvas = result.baseElement.querySelector("canvas.xterm-text-layer") as HTMLCanvasElement;
|
||||
});
|
||||
|
||||
it("renders", () => {
|
||||
expect(result.baseElement).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("opens tab", () => {
|
||||
const terminalTabContents = result.queryByTestId("dock-tab-content-for-terminal");
|
||||
|
||||
expect(terminalTabContents).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows connecting message", async () => {
|
||||
expect(convertCanvasToPngBuffer(textCanvas)).toMatchImageSnapshot();
|
||||
});
|
||||
|
||||
it.skip("connects websocket to main", () => {
|
||||
|
||||
});
|
||||
|
||||
it.skip("displays the values on screen", () => {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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 assert from "assert";
|
||||
import hostedClusterIdInjectable from "../../../renderer/cluster-frame-context/hosted-cluster-id.injectable";
|
||||
import requestFromChannelInjectable from "../../../renderer/utils/channel/request-from-channel.injectable";
|
||||
import { shellApiAuthChannel } from "../common/shell-api-auth-channel";
|
||||
|
||||
export type RequestShellApiToken = (tabId: string) => Promise<Uint8Array>;
|
||||
|
||||
const requestShellApiTokenInjectable = getInjectable({
|
||||
id: "request-shell-api-token",
|
||||
instantiate: (di): RequestShellApiToken => {
|
||||
const hostedClusterId = di.inject(hostedClusterIdInjectable);
|
||||
const requestChannel = di.inject(requestFromChannelInjectable);
|
||||
|
||||
return (tabId) => {
|
||||
assert(hostedClusterId, "Can only request shell access within a cluster frame");
|
||||
|
||||
return requestChannel(shellApiAuthChannel, {
|
||||
clusterId: hostedClusterId,
|
||||
tabId,
|
||||
});
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default requestShellApiTokenInjectable;
|
||||
@ -4,3 +4,6 @@
|
||||
*/
|
||||
|
||||
import "@testing-library/jest-dom";
|
||||
import { toMatchImageSnapshot } from "jest-image-snapshot";
|
||||
|
||||
expect.extend({ toMatchImageSnapshot });
|
||||
|
||||
@ -9,6 +9,7 @@ import { TextEncoder, TextDecoder as TextDecoderNode } from "util";
|
||||
import glob from "glob";
|
||||
import path from "path";
|
||||
import { enableMapSet, setAutoFreeze } from "immer";
|
||||
import { WebSocket } from "ws";
|
||||
|
||||
declare global {
|
||||
interface InjectablePaths {
|
||||
@ -52,11 +53,30 @@ global.ResizeObserver = class {
|
||||
disconnect = () => {};
|
||||
};
|
||||
|
||||
global.WebSocket = WebSocket as any;
|
||||
|
||||
jest.mock("./renderer/components/monaco-editor/monaco-editor");
|
||||
jest.mock("./renderer/components/tooltip/withTooltip");
|
||||
|
||||
jest.mock("monaco-editor");
|
||||
|
||||
/**
|
||||
* This is the official workaround https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
|
||||
*/
|
||||
Object.defineProperty(window, "matchMedia", {
|
||||
writable: true,
|
||||
value: jest.fn().mockImplementation((query) => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: jest.fn(), // Deprecated
|
||||
removeListener: jest.fn(), // Deprecated
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
dispatchEvent: jest.fn(),
|
||||
})),
|
||||
});
|
||||
|
||||
const getInjectables = (environment: "renderer" | "main", filePathGlob: string) => [
|
||||
...glob.sync(`./{common,extensions,${environment}}/**/${filePathGlob}`, {
|
||||
cwd: __dirname,
|
||||
|
||||
48
src/main/cluster/get-cluster-for-request.injectable.ts
Normal file
48
src/main/cluster/get-cluster-for-request.injectable.ts
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* 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 type { IncomingMessage } from "http";
|
||||
import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable";
|
||||
import type { Cluster } from "../../common/cluster/cluster";
|
||||
import { getClusterIdFromHost } from "../../common/utils";
|
||||
import { apiKubePrefix } from "../../common/vars";
|
||||
|
||||
export type GetClusterForRequest = (req: IncomingMessage) => Cluster | undefined;
|
||||
|
||||
const getClusterForRequestInjectable = getInjectable({
|
||||
id: "get-cluster-for-request",
|
||||
instantiate: (di): GetClusterForRequest => {
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
|
||||
return (req) => {
|
||||
if (!req.headers.host) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// lens-server is connecting to 127.0.0.1:<port>/<uid>
|
||||
if (req.url && req.headers.host.startsWith("127.0.0.1")) {
|
||||
const clusterId = req.url.split("/")[1];
|
||||
const cluster = getClusterById(clusterId);
|
||||
|
||||
if (cluster) {
|
||||
// we need to swap path prefix so that request is proxied to kube api
|
||||
req.url = req.url.replace(`/${clusterId}`, apiKubePrefix);
|
||||
}
|
||||
|
||||
return cluster;
|
||||
}
|
||||
|
||||
const clusterId = getClusterIdFromHost(req.headers.host);
|
||||
|
||||
if (!clusterId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getClusterById(clusterId);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export default getClusterForRequestInjectable;
|
||||
@ -5,6 +5,7 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import clusterStoreInjectable from "../../common/cluster-store/cluster-store.injectable";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable";
|
||||
import catalogEntityRegistryInjectable from "../catalog/entity-registry.injectable";
|
||||
import clustersThatAreBeingDeletedInjectable from "./are-being-deleted.injectable";
|
||||
import { ClusterManager } from "./manager";
|
||||
@ -19,6 +20,7 @@ const clusterManagerInjectable = getInjectable({
|
||||
clustersThatAreBeingDeleted: di.inject(clustersThatAreBeingDeletedInjectable),
|
||||
visibleCluster: di.inject(visibleClusterInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
getClusterById: di.inject(getClusterByIdInjectable),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@ -16,12 +16,14 @@ import type { ClusterStore } from "../../common/cluster-store/cluster-store";
|
||||
import type { ClusterId } from "../../common/cluster-types";
|
||||
import type { CatalogEntityRegistry } from "../catalog";
|
||||
import type { Logger } from "../../common/logger";
|
||||
import type { GetClusterById } from "../../common/cluster-store/get-by-id.injectable";
|
||||
|
||||
const logPrefix = "[CLUSTER-MANAGER]:";
|
||||
|
||||
const lensSpecificClusterStatuses: Set<string> = new Set(Object.values(LensKubernetesClusterStatus));
|
||||
|
||||
interface Dependencies {
|
||||
getClusterById: GetClusterById;
|
||||
readonly store: ClusterStore;
|
||||
readonly catalogEntityRegistry: CatalogEntityRegistry;
|
||||
readonly clustersThatAreBeingDeleted: ObservableSet<ClusterId>;
|
||||
@ -181,7 +183,7 @@ export class ClusterManager {
|
||||
@action
|
||||
protected syncClustersFromCatalog(entities: KubernetesCluster[]) {
|
||||
for (const entity of entities) {
|
||||
const cluster = this.dependencies.store.getById(entity.getId());
|
||||
const cluster = this.dependencies.getClusterById(entity.getId());
|
||||
|
||||
if (!cluster) {
|
||||
const model = {
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { getGlobalOverride } from "../../../common/test-utils/get-global-override";
|
||||
import showErrorPopupInjectable from "./show-error-popup.injectable";
|
||||
|
||||
export default getGlobalOverride(showErrorPopupInjectable, () => () => {
|
||||
throw new Error("Tried to show an error popup without an override");
|
||||
});
|
||||
@ -5,15 +5,15 @@
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import electronDialogInjectable from "./electron-dialog.injectable";
|
||||
|
||||
export type ShowErrorPopup = (heading: string, message: string) => void;
|
||||
|
||||
const showErrorPopupInjectable = getInjectable({
|
||||
id: "show-error-popup",
|
||||
|
||||
instantiate: (di) => {
|
||||
instantiate: (di): ShowErrorPopup => {
|
||||
const dialog = di.inject(electronDialogInjectable);
|
||||
|
||||
return (heading: string, message: string) => {
|
||||
dialog.showErrorBox(heading, message);
|
||||
};
|
||||
return (heading, message) => dialog.showErrorBox(heading, message);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@ import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as
|
||||
import spawnInjectable from "./child-process/spawn.injectable";
|
||||
import initializeExtensionsInjectable from "./start-main-application/runnables/initialize-extensions.injectable";
|
||||
import setupIpcMainHandlersInjectable from "./electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable";
|
||||
import setupLensProxyInjectable from "./start-main-application/runnables/setup-lens-proxy.injectable";
|
||||
import setupSyncingOfWeblinksInjectable from "./start-main-application/runnables/setup-syncing-of-weblinks.injectable";
|
||||
import setupDeepLinkingInjectable from "./electron-app/runnables/setup-deep-linking.injectable";
|
||||
import setupMainWindowVisibilityAfterActivationInjectable from "./electron-app/runnables/setup-main-window-visibility-after-activation.injectable";
|
||||
@ -103,7 +102,6 @@ const overrideRunnablesHavingSideEffects = (di: DiContainer) => {
|
||||
initializeExtensionsInjectable,
|
||||
initializeClusterManagerInjectable,
|
||||
setupIpcMainHandlersInjectable,
|
||||
setupLensProxyInjectable,
|
||||
setupSyncingOfWeblinksInjectable,
|
||||
].forEach((injectable) => {
|
||||
di.override(injectable, () => ({
|
||||
|
||||
@ -10,7 +10,6 @@ import type httpProxy from "http-proxy";
|
||||
import { apiPrefix, apiKubePrefix } from "../../common/vars";
|
||||
import type { Router } from "../router/router";
|
||||
import type { ClusterContextHandler } from "../context-handler/context-handler";
|
||||
import type { Cluster } from "../../common/cluster/cluster";
|
||||
import type { ProxyApiRequestArgs } from "./proxy-functions";
|
||||
import { getBoolean } from "../utils/parse-query";
|
||||
import assert from "assert";
|
||||
@ -18,8 +17,8 @@ import type { SetRequired } from "type-fest";
|
||||
import type { EmitAppEvent } from "../../common/app-event-bus/emit-event.injectable";
|
||||
import type { Logger } from "../../common/logger";
|
||||
import type { SelfSignedCert } from "selfsigned";
|
||||
import type { GetClusterForRequest } from "../cluster/get-cluster-for-request.injectable";
|
||||
|
||||
export type GetClusterForRequest = (req: http.IncomingMessage) => Cluster | undefined;
|
||||
export type ServerIncomingMessage = SetRequired<http.IncomingMessage, "url" | "method">;
|
||||
export type LensProxyApiRequest = (args: ProxyApiRequestArgs) => void | Promise<void>;
|
||||
|
||||
@ -115,7 +114,6 @@ export class LensProxy {
|
||||
const { address, port } = this.proxyServer.address() as net.AddressInfo;
|
||||
|
||||
this.dependencies.lensProxyPort.set(port);
|
||||
|
||||
this.dependencies.logger.info(`[LENS-PROXY]: Proxy server has started at ${address}:${port}`);
|
||||
|
||||
this.proxyServer.on("error", (error) => {
|
||||
|
||||
@ -82,7 +82,7 @@ const setupLensProxyInjectable = getInjectable({
|
||||
};
|
||||
},
|
||||
|
||||
causesSideEffects: true,
|
||||
// causesSideEffects: true,
|
||||
|
||||
injectionToken: beforeApplicationIsLoadingInjectionToken,
|
||||
});
|
||||
|
||||
@ -6,7 +6,7 @@ import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { IpcMainInvokeEvent } from "electron";
|
||||
import ipcMainInjectable from "../ipc-main/ipc-main.injectable";
|
||||
import type { Disposer } from "../../../../common/utils";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel";
|
||||
import type { RequestChannelListener } from "./listener-tokens";
|
||||
|
||||
export type EnlistRequestChannelListener = <TChannel extends RequestChannel<unknown, unknown>>(listener: RequestChannelListener<TChannel>) => Disposer;
|
||||
|
||||
@ -8,7 +8,7 @@ import type { IpcMain, IpcMainInvokeEvent } from "electron";
|
||||
import { getPromiseStatus } from "../../../../common/test-utils/get-promise-status";
|
||||
import type { AsyncFnMock } from "@async-fn/jest";
|
||||
import asyncFn from "@async-fn/jest";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel";
|
||||
import type { EnlistRequestChannelListener } from "./enlist-request-channel-listener.injectable";
|
||||
import enlistRequestChannelListenerInjectable from "./enlist-request-channel-listener.injectable";
|
||||
import type { RequestChannelHandler } from "./listener-tokens";
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
|
||||
import type { DiContainerForInjection } from "@ogre-tools/injectable";
|
||||
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel";
|
||||
|
||||
export type RequestChannelHandler<Channel> = Channel extends RequestChannel<infer Request, infer Response>
|
||||
? (req: Request) => Promise<Response> | Response
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { disposer } from "../../../../common/utils";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import { getStartableStoppable } from "../../../../common/utils/get-startable-stoppable";
|
||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel";
|
||||
import enlistRequestChannelListenerInjectable from "./enlist-request-channel-listener.injectable";
|
||||
import { requestChannelListenerInjectionToken } from "./listener-tokens";
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
|
||||
import getClusterByIdInjectable from "../../../../common/cluster-store/get-by-id.injectable";
|
||||
import type { Cluster } from "../../../../common/cluster/cluster";
|
||||
import catalogEntityRegistryInjectable from "./registry.injectable";
|
||||
|
||||
@ -12,10 +12,18 @@ export type GetActiveClusterEntity = () => Cluster | undefined;
|
||||
const getActiveClusterEntityInjectable = getInjectable({
|
||||
id: "get-active-cluster-entity",
|
||||
instantiate: (di): GetActiveClusterEntity => {
|
||||
const store = di.inject(clusterStoreInjectable);
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
const entityRegistry = di.inject(catalogEntityRegistryInjectable);
|
||||
|
||||
return () => store.getById(entityRegistry.activeEntity?.getId());
|
||||
return () => {
|
||||
const clusterId = entityRegistry.activeEntity?.getId();
|
||||
|
||||
if (!clusterId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getClusterById(clusterId);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import assert from "assert";
|
||||
import loggerInjectable from "../../common/logger.injectable";
|
||||
import hostedClusterIdInjectable from "../cluster-frame-context/hosted-cluster-id.injectable";
|
||||
import defaultWebsocketApiParamsInjectable from "./default-websocket-api-params.injectable";
|
||||
import requestShellApiTokenInjectable from "../../features/terminal/renderer/request-shell-api-token.injectable";
|
||||
import currentLocationInjectable from "./current-location.injectable";
|
||||
import defaultWebsocketApiParamsInjectable from "./default-websocket-params.injectable";
|
||||
import type { TerminalApiDependencies, TerminalApiQuery } from "./terminal-api";
|
||||
import { TerminalApi } from "./terminal-api";
|
||||
|
||||
@ -15,20 +15,14 @@ export type CreateTerminalApi = (query: TerminalApiQuery) => TerminalApi;
|
||||
const createTerminalApiInjectable = getInjectable({
|
||||
id: "create-terminal-api",
|
||||
instantiate: (di): CreateTerminalApi => {
|
||||
const hostedClusterId = di.inject(hostedClusterIdInjectable);
|
||||
const deps: Omit<TerminalApiDependencies, "hostedClusterId"> = {
|
||||
logger: di.inject(loggerInjectable),
|
||||
const deps: TerminalApiDependencies = {
|
||||
requestShellApiToken: di.inject(requestShellApiTokenInjectable),
|
||||
defaultParams: di.inject(defaultWebsocketApiParamsInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
currentLocation: di.inject(currentLocationInjectable),
|
||||
};
|
||||
|
||||
return (query) => {
|
||||
assert(hostedClusterId, "Can only create terminal APIs within a cluster frame");
|
||||
|
||||
return new TerminalApi({
|
||||
hostedClusterId,
|
||||
...deps,
|
||||
}, query);
|
||||
};
|
||||
return (query) => new TerminalApi(deps, query);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
23
src/renderer/api/current-location.injectable.ts
Normal file
23
src/renderer/api/current-location.injectable.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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";
|
||||
|
||||
export interface CurrentLocation {
|
||||
hostname: string;
|
||||
port: string;
|
||||
protocol: string;
|
||||
}
|
||||
|
||||
const currentLocationInjectable = getInjectable({
|
||||
id: "current-location",
|
||||
instantiate: (): CurrentLocation => ({
|
||||
hostname: location.hostname,
|
||||
port: location.port,
|
||||
protocol: location.protocol,
|
||||
}),
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default currentLocationInjectable;
|
||||
@ -8,10 +8,11 @@ import { WebSocketApi } from "./websocket-api";
|
||||
import isEqual from "lodash/isEqual";
|
||||
import url from "url";
|
||||
import { makeObservable, observable } from "mobx";
|
||||
import { ipcRenderer } from "electron";
|
||||
import type { Logger } from "../../common/logger";
|
||||
import { once } from "lodash";
|
||||
import { type TerminalMessage, TerminalChannels } from "../../common/terminal/channels";
|
||||
import type { RequestShellApiToken } from "../../features/terminal/renderer/request-shell-api-token.injectable";
|
||||
import type { CurrentLocation } from "./current-location.injectable";
|
||||
|
||||
enum TerminalColor {
|
||||
RED = "\u001b[31m",
|
||||
@ -38,8 +39,13 @@ export interface TerminalEvents extends WebSocketEvents {
|
||||
}
|
||||
|
||||
export interface TerminalApiDependencies extends WebSocketApiDependencies {
|
||||
readonly hostedClusterId: string;
|
||||
readonly logger: Logger;
|
||||
readonly currentLocation: CurrentLocation;
|
||||
requestShellApiToken: RequestShellApiToken;
|
||||
}
|
||||
|
||||
export interface ConnectOpts {
|
||||
signal: AbortSignal;
|
||||
}
|
||||
|
||||
export class TerminalApi extends WebSocketApi<TerminalEvents> {
|
||||
@ -68,13 +74,8 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
|
||||
this.emitStatus("Connecting ...");
|
||||
}
|
||||
|
||||
const authTokenArray = await ipcRenderer.invoke("cluster:shell-api", this.dependencies.hostedClusterId, this.query.id);
|
||||
|
||||
if (!(authTokenArray instanceof Uint8Array)) {
|
||||
throw new TypeError("ShellApi token is not a Uint8Array");
|
||||
}
|
||||
|
||||
const { hostname, protocol, port } = location;
|
||||
const authTokenArray = await this.dependencies.requestShellApiToken(this.query.id);
|
||||
const { hostname, protocol, port } = this.dependencies.currentLocation;
|
||||
const socketUrl = url.format({
|
||||
protocol: protocol.includes("https") ? "wss" : "ws",
|
||||
hostname,
|
||||
@ -110,8 +111,7 @@ export class TerminalApi extends WebSocketApi<TerminalEvents> {
|
||||
|
||||
this.prependListener("data", onReady);
|
||||
this.prependListener("connected", onReady);
|
||||
|
||||
super.connect(socketUrl);
|
||||
this.connectTo(socketUrl);
|
||||
}
|
||||
|
||||
sendMessage(message: TerminalMessage) {
|
||||
|
||||
@ -8,6 +8,7 @@ import EventEmitter from "events";
|
||||
import type TypedEventEmitter from "typed-emitter";
|
||||
import type { Defaulted } from "../utils";
|
||||
import type { DefaultWebsocketApiParams } from "./default-websocket-params.injectable";
|
||||
import type { Logger } from "../../common/logger";
|
||||
|
||||
interface WebsocketApiParams {
|
||||
/**
|
||||
@ -64,6 +65,7 @@ export interface WebSocketEvents {
|
||||
|
||||
export interface WebSocketApiDependencies {
|
||||
readonly defaultParams: DefaultWebsocketApiParams;
|
||||
readonly logger: Logger;
|
||||
}
|
||||
|
||||
export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter as { new<T>(): TypedEventEmitter<T> })<Events> {
|
||||
@ -93,7 +95,7 @@ export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter
|
||||
return this.socket?.readyState === WebSocket.OPEN;
|
||||
}
|
||||
|
||||
connect(url: string) {
|
||||
connectTo(url: string) {
|
||||
// close previous connection first
|
||||
this.socket?.close();
|
||||
|
||||
@ -114,10 +116,10 @@ export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter
|
||||
|
||||
reconnect(): void {
|
||||
if (!this.socket) {
|
||||
return void console.error("[WEBSOCKET-API]: cannot reconnect to a socket that is not connected");
|
||||
return this.dependencies.logger.error("[WEBSOCKET-API]: cannot reconnect to a socket that is not connected");
|
||||
}
|
||||
|
||||
this.connect(this.socket.url);
|
||||
this.connectTo(this.socket.url);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
@ -182,7 +184,7 @@ export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter
|
||||
|
||||
this.writeLog("will reconnect in", `${reconnectDelay}s`);
|
||||
|
||||
this.reconnectTimer = window.setTimeout(() => this.connect(url), reconnectDelay * 1000);
|
||||
this.reconnectTimer = window.setTimeout(() => this.connectTo(url), reconnectDelay * 1000);
|
||||
this.readyState = WebSocketApiState.RECONNECTING;
|
||||
}
|
||||
} else {
|
||||
@ -192,9 +194,9 @@ export class WebSocketApi<Events extends WebSocketEvents> extends (EventEmitter
|
||||
this.writeLog("%cCLOSE", `color:${error ? "red" : "black"};font-weight:bold;`, evt);
|
||||
}
|
||||
|
||||
protected writeLog(...data: any[]) {
|
||||
protected writeLog(message: string, ...data: any[]) {
|
||||
if (this.params.logging) {
|
||||
console.debug(...data);
|
||||
this.dependencies.logger.debug(message, ...data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,16 +4,20 @@
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import hostedClusterIdInjectable from "./hosted-cluster-id.injectable";
|
||||
import clusterStoreInjectable from "../../common/cluster-store/cluster-store.injectable";
|
||||
import getClusterByIdInjectable from "../../common/cluster-store/get-by-id.injectable";
|
||||
|
||||
const hostedClusterInjectable = getInjectable({
|
||||
id: "hosted-cluster",
|
||||
|
||||
instantiate: (di) => {
|
||||
const hostedClusterId = di.inject(hostedClusterIdInjectable);
|
||||
const store = di.inject(clusterStoreInjectable);
|
||||
const getClusterById = di.inject(getClusterByIdInjectable);
|
||||
|
||||
return store.getById(hostedClusterId);
|
||||
if (!hostedClusterId) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return getClusterById(hostedClusterId);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* 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 type { ITerminalOptions } from "xterm";
|
||||
import { Terminal } from "xterm";
|
||||
|
||||
export type CreateTerminalRenderer = (opts: ITerminalOptions) => Terminal;
|
||||
|
||||
const createTerminalRendererInjectable = getInjectable({
|
||||
id: "create-terminal-renderer",
|
||||
instantiate: (): CreateTerminalRenderer => (params) => new Terminal(params),
|
||||
});
|
||||
|
||||
export default createTerminalRendererInjectable;
|
||||
@ -13,6 +13,7 @@ import terminalCopyOnSelectInjectable from "../../../../common/user-store/termin
|
||||
import isMacInjectable from "../../../../common/vars/is-mac.injectable";
|
||||
import openLinkInBrowserInjectable from "../../../../common/utils/open-link-in-browser.injectable";
|
||||
import xtermColorThemeInjectable from "../../../themes/terminal-colors.injectable";
|
||||
import createTerminalRendererInjectable from "./create-renderer.injectable";
|
||||
import loggerInjectable from "../../../../common/logger.injectable";
|
||||
|
||||
export type CreateTerminal = (tabId: TabId, api: TerminalApi) => Terminal;
|
||||
@ -24,10 +25,11 @@ const createTerminalInjectable = getInjectable({
|
||||
spawningPool: di.inject(terminalSpawningPoolInjectable),
|
||||
terminalConfig: di.inject(terminalConfigInjectable),
|
||||
terminalCopyOnSelect: di.inject(terminalCopyOnSelectInjectable),
|
||||
isMac: di.inject(isMacInjectable),
|
||||
openLinkInBrowser: di.inject(openLinkInBrowserInjectable),
|
||||
xtermColorTheme: di.inject(xtermColorThemeInjectable),
|
||||
isMac: di.inject(isMacInjectable),
|
||||
logger: di.inject(loggerInjectable),
|
||||
openLinkInBrowser: di.inject(openLinkInBrowserInjectable),
|
||||
createTerminalRenderer: di.inject(createTerminalRendererInjectable),
|
||||
};
|
||||
|
||||
return (tabId, api) => new Terminal(dependencies, { tabId, api });
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
|
||||
import { action, observable } from "mobx";
|
||||
import { action, runInAction } from "mobx";
|
||||
import type { Terminal } from "./terminal";
|
||||
import type { TerminalApi } from "../../../api/terminal-api";
|
||||
import type { DockTab, TabId } from "../dock/store";
|
||||
@ -20,69 +20,71 @@ interface Dependencies {
|
||||
createTerminalApi: CreateTerminalApi;
|
||||
}
|
||||
|
||||
export interface TerminalConnection {
|
||||
terminal: Terminal;
|
||||
api: TerminalApi;
|
||||
}
|
||||
|
||||
export interface TerminalConnectOptions {
|
||||
signal: AbortSignal;
|
||||
}
|
||||
|
||||
export class TerminalStore {
|
||||
protected terminals = new Map<TabId, Terminal>();
|
||||
protected connections = observable.map<TabId, TerminalApi>();
|
||||
private readonly connections = new Map<TabId, TerminalConnection>();
|
||||
|
||||
constructor(private dependencies: Dependencies) {
|
||||
}
|
||||
constructor(private readonly dependencies: Dependencies) {}
|
||||
|
||||
@action
|
||||
connect(tab: ITerminalTab) {
|
||||
if (this.isConnected(tab.id)) {
|
||||
return;
|
||||
connect(tab: ITerminalTab): TerminalConnection & { connectionPromise?: Promise<void> } {
|
||||
{
|
||||
const connection = this.connections.get(tab.id);
|
||||
|
||||
if (connection) {
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
||||
const api = this.dependencies.createTerminalApi({
|
||||
id: tab.id,
|
||||
node: tab.node,
|
||||
});
|
||||
const terminal = this.dependencies.createTerminal(tab.id, api);
|
||||
|
||||
this.connections.set(tab.id, api);
|
||||
this.terminals.set(tab.id, terminal);
|
||||
runInAction(() => {
|
||||
this.connections.set(tab.id, { api, terminal });
|
||||
});
|
||||
|
||||
api.connect();
|
||||
const connectionPromise = api.connect();
|
||||
|
||||
return { terminal, api, connectionPromise };
|
||||
}
|
||||
|
||||
@action
|
||||
destroy(tabId: TabId) {
|
||||
const terminal = this.terminals.get(tabId);
|
||||
const terminalApi = this.connections.get(tabId);
|
||||
const { terminal, api } = this.connections.get(tabId) ?? {};
|
||||
|
||||
terminal?.destroy();
|
||||
terminalApi?.destroy();
|
||||
api?.destroy();
|
||||
|
||||
this.connections.delete(tabId);
|
||||
this.terminals.delete(tabId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use `this.destroy()` instead
|
||||
*/
|
||||
disconnect(tabId: TabId) {
|
||||
this.destroy(tabId);
|
||||
async reconnect(tabId: TabId): Promise<void> {
|
||||
await this.connections.get(tabId)?.api.connect();
|
||||
}
|
||||
|
||||
reconnect(tabId: TabId) {
|
||||
this.connections.get(tabId)?.connect();
|
||||
isDisconnected(tabId: TabId): boolean {
|
||||
return this.connections.get(tabId)?.api.readyState === WebSocketApiState.CLOSED;
|
||||
}
|
||||
|
||||
isConnected(tabId: TabId) {
|
||||
return Boolean(this.connections.get(tabId));
|
||||
getTerminal(tabId: TabId): Terminal | undefined {
|
||||
return this.connections.get(tabId)?.terminal;
|
||||
}
|
||||
|
||||
isDisconnected(tabId: TabId) {
|
||||
return this.connections.get(tabId)?.readyState === WebSocketApiState.CLOSED;
|
||||
getTerminalApi(tabId: TabId): TerminalApi | undefined {
|
||||
return this.connections.get(tabId)?.api;
|
||||
}
|
||||
|
||||
getTerminal(tabId: TabId) {
|
||||
return this.terminals.get(tabId);
|
||||
}
|
||||
|
||||
getTerminalApi(tabId: TabId) {
|
||||
return this.connections.get(tabId);
|
||||
}
|
||||
|
||||
reset() {
|
||||
reset(): void {
|
||||
[...this.connections].forEach(([tabId]) => {
|
||||
this.destroy(tabId);
|
||||
});
|
||||
|
||||
@ -14,7 +14,6 @@ const terminalSpawningPoolInjectable = getInjectable({
|
||||
|
||||
return pool;
|
||||
},
|
||||
causesSideEffects: true,
|
||||
});
|
||||
|
||||
export default terminalSpawningPoolInjectable;
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
import debounce from "lodash/debounce";
|
||||
import type { IComputedValue } from "mobx";
|
||||
import { reaction } from "mobx";
|
||||
import { Terminal as XTerm } from "xterm";
|
||||
import type { Terminal as XTerminal } from "xterm";
|
||||
import { FitAddon } from "xterm-addon-fit";
|
||||
import type { TabId } from "../dock/store";
|
||||
import type { TerminalApi } from "../../../api/terminal-api";
|
||||
@ -19,6 +19,7 @@ import assert from "assert";
|
||||
import { TerminalChannels } from "../../../../common/terminal/channels";
|
||||
import { LinkProvider } from "xterm-link-provider";
|
||||
import type { OpenLinkInBrowser } from "../../../../common/utils/open-link-in-browser.injectable";
|
||||
import type { CreateTerminalRenderer } from "./create-renderer.injectable";
|
||||
|
||||
export interface TerminalDependencies {
|
||||
readonly spawningPool: HTMLElement;
|
||||
@ -28,6 +29,7 @@ export interface TerminalDependencies {
|
||||
readonly xtermColorTheme: IComputedValue<Record<string, string>>;
|
||||
readonly logger: Logger;
|
||||
openLinkInBrowser: OpenLinkInBrowser;
|
||||
createTerminalRenderer: CreateTerminalRenderer;
|
||||
}
|
||||
|
||||
export interface TerminalArguments {
|
||||
@ -36,7 +38,7 @@ export interface TerminalArguments {
|
||||
}
|
||||
|
||||
export class Terminal {
|
||||
private readonly xterm: XTerm;
|
||||
private readonly xterm: XTerminal;
|
||||
private readonly fitAddon = new FitAddon();
|
||||
private scrollPos = 0;
|
||||
private readonly disposer = disposer();
|
||||
@ -44,13 +46,19 @@ export class Terminal {
|
||||
protected readonly api: TerminalApi;
|
||||
|
||||
private get elem() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
return this.xterm.element!;
|
||||
const { element } = this.xterm;
|
||||
|
||||
assert(element, "Terminal element must be mounted");
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
private get viewport() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
return this.elem.querySelector(".xterm-viewport")!;
|
||||
const viewport = this.elem.querySelector(".xterm-viewport");
|
||||
|
||||
assert(viewport, 'Terminal element must have a descendant with a className of ".xterm-viewport"');
|
||||
|
||||
return viewport;
|
||||
}
|
||||
|
||||
attachTo(parentElem: HTMLElement) {
|
||||
@ -67,11 +75,11 @@ export class Terminal {
|
||||
}
|
||||
}
|
||||
|
||||
get fontFamily() {
|
||||
private get fontFamily() {
|
||||
return this.dependencies.terminalConfig.get().fontFamily;
|
||||
}
|
||||
|
||||
get fontSize() {
|
||||
private get fontSize() {
|
||||
return this.dependencies.terminalConfig.get().fontSize;
|
||||
}
|
||||
|
||||
@ -82,11 +90,12 @@ export class Terminal {
|
||||
this.tabId = tabId;
|
||||
this.api = api;
|
||||
|
||||
this.xterm = new XTerm({
|
||||
this.xterm = this.dependencies.createTerminalRenderer({
|
||||
cursorBlink: true,
|
||||
cursorStyle: "bar",
|
||||
fontSize: this.fontSize,
|
||||
fontFamily: this.fontFamily,
|
||||
theme: this.dependencies.xtermColorTheme.get(),
|
||||
});
|
||||
// enable terminal addons
|
||||
this.xterm.loadAddon(this.fitAddon);
|
||||
@ -96,7 +105,6 @@ export class Terminal {
|
||||
this.xterm.onSelectionChange(this.onSelectionChange);
|
||||
|
||||
// bind events
|
||||
const onDataHandler = this.xterm.onData(this.onData);
|
||||
const clearOnce = once(this.onClear);
|
||||
|
||||
this.viewport.addEventListener("scroll", this.onScroll);
|
||||
@ -117,15 +125,13 @@ export class Terminal {
|
||||
|
||||
this.disposer.push(
|
||||
this.xterm.registerLinkProvider(linkProvider),
|
||||
reaction(() => this.dependencies.xtermColorTheme.get(),
|
||||
reaction(
|
||||
() => this.dependencies.xtermColorTheme.get(),
|
||||
colors => this.xterm.options.theme = colors,
|
||||
{
|
||||
fireImmediately: true,
|
||||
},
|
||||
),
|
||||
reaction(() => this.fontSize, this.setFontSize, { fireImmediately: true }),
|
||||
reaction(() => this.fontFamily, this.setFontFamily, { fireImmediately: true }),
|
||||
() => onDataHandler.dispose(),
|
||||
reaction(() => this.fontSize, this.setFontSize),
|
||||
reaction(() => this.fontFamily, this.setFontFamily),
|
||||
this.xterm.onData(this.onData),
|
||||
() => this.fitAddon.dispose(),
|
||||
() => this.api.removeAllListeners(),
|
||||
() => window.removeEventListener("resize", this.onResize),
|
||||
|
||||
@ -5,8 +5,7 @@
|
||||
|
||||
import "./terminal-window.scss";
|
||||
|
||||
import React from "react";
|
||||
import { disposeOnUnmount, observer } from "mobx-react";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { cssNames } from "../../../utils";
|
||||
import type { Terminal } from "./terminal";
|
||||
import type { TerminalStore } from "./store";
|
||||
@ -15,7 +14,6 @@ import type { DockTab, DockStore } from "../dock/store";
|
||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||
import dockStoreInjectable from "../dock/store.injectable";
|
||||
import terminalStoreInjectable from "./store.injectable";
|
||||
import assert from "assert";
|
||||
import activeThemeInjectable from "../../../themes/active.injectable";
|
||||
import type { IComputedValue } from "mobx";
|
||||
|
||||
@ -29,52 +27,41 @@ interface Dependencies {
|
||||
activeTheme: IComputedValue<LensTheme>;
|
||||
}
|
||||
|
||||
@observer
|
||||
class NonInjectedTerminalWindow extends React.Component<TerminalWindowProps & Dependencies> {
|
||||
public elem: HTMLElement | null = null;
|
||||
public terminal!: Terminal;
|
||||
const NonInjectedTerminalWindow = (props: TerminalWindowProps & Dependencies) => {
|
||||
const {
|
||||
activeTheme,
|
||||
dockStore,
|
||||
tab,
|
||||
terminalStore,
|
||||
} = props;
|
||||
|
||||
componentDidMount() {
|
||||
this.props.terminalStore.connect(this.props.tab);
|
||||
const terminal = this.props.terminalStore.getTerminal(this.props.tab.id);
|
||||
const [terminal, setTerminal] = useState<Terminal>();
|
||||
const element = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
assert(terminal, "Terminal must be created for tab before mounting");
|
||||
this.terminal = terminal;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
this.terminal.attachTo(this.elem!);
|
||||
useEffect(() => {
|
||||
const { terminal } = terminalStore.connect(tab);
|
||||
|
||||
disposeOnUnmount(this, [
|
||||
// refresh terminal available space (cols/rows) when <Dock/> resized
|
||||
this.props.dockStore.onResize(() => this.terminal.onResize(), {
|
||||
fireImmediately: true,
|
||||
}),
|
||||
]);
|
||||
}
|
||||
setTerminal(terminal);
|
||||
|
||||
componentDidUpdate(): void {
|
||||
this.terminal.detach();
|
||||
this.props.terminalStore.connect(this.props.tab);
|
||||
const terminal = this.props.terminalStore.getTerminal(this.props.tab.id);
|
||||
if (element.current) {
|
||||
terminal.attachTo(element.current);
|
||||
}
|
||||
}, [tab.id]);
|
||||
|
||||
assert(terminal, "Terminal must be created for tab before mounting");
|
||||
this.terminal = terminal;
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
this.terminal.attachTo(this.elem!);
|
||||
}
|
||||
useEffect(() => dockStore.onResize(
|
||||
() => {
|
||||
terminal?.onResize();
|
||||
}, {
|
||||
fireImmediately: true,
|
||||
}), []);
|
||||
|
||||
componentWillUnmount(): void {
|
||||
this.terminal.detach();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
className={cssNames("TerminalWindow", this.props.activeTheme.get().type)}
|
||||
ref={elem => this.elem = elem}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className={cssNames("TerminalWindow", activeTheme.get().type)}
|
||||
ref={element}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const TerminalWindow = withInjectables<Dependencies, TerminalWindowProps>(NonInjectedTerminalWindow, {
|
||||
getProps: (di, props) => ({
|
||||
|
||||
@ -21,7 +21,6 @@ import { filter, first, join, last, map, matches } from "lodash/fp";
|
||||
import navigateToPreferencesInjectable from "../../../features/preferences/common/navigate-to-preferences.injectable";
|
||||
import type { NavigateToHelmCharts } from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable";
|
||||
import navigateToHelmChartsInjectable from "../../../common/front-end-routing/routes/cluster/helm/charts/navigate-to-helm-charts.injectable";
|
||||
import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable";
|
||||
import type { Cluster } from "../../../common/cluster/cluster";
|
||||
import startMainApplicationInjectable from "../../../main/start-main-application/start-main-application.injectable";
|
||||
import startFrameInjectable from "../../start-frame/start-frame.injectable";
|
||||
@ -35,7 +34,6 @@ import { overrideChannels } from "../../../test-utils/channel-fakes/override-cha
|
||||
import assert from "assert";
|
||||
import { openMenu } from "react-select-event";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import lensProxyPortInjectable from "../../../main/lens-proxy/lens-proxy-port.injectable";
|
||||
import type { Route } from "../../../common/front-end-routing/front-end-route-injection-token";
|
||||
import type { NavigateToRouteOptions } from "../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||
import { navigateToRouteInjectionToken } from "../../../common/front-end-routing/navigate-to-route-injection-token";
|
||||
@ -46,8 +44,6 @@ import { renderFor } from "./renderFor";
|
||||
import { RootFrame } from "../../frames/root-frame/root-frame";
|
||||
import { ClusterFrame } from "../../frames/cluster-frame/cluster-frame";
|
||||
import hostedClusterIdInjectable from "../../cluster-frame-context/hosted-cluster-id.injectable";
|
||||
import activeKubernetesClusterInjectable from "../../cluster-frame-context/active-kubernetes-cluster.injectable";
|
||||
import { catalogEntityFromCluster } from "../../../main/cluster/manager";
|
||||
import namespaceStoreInjectable from "../+namespaces/store.injectable";
|
||||
import createApplicationWindowInjectable from "../../../main/start-main-application/lens-window/application-window/create-application-window.injectable";
|
||||
import type { CreateElectronWindow } from "../../../main/start-main-application/lens-window/application-window/create-electron-window.injectable";
|
||||
@ -69,6 +65,12 @@ import fsInjectable from "../../../common/fs/fs.injectable";
|
||||
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
|
||||
import homeDirectoryPathInjectable from "../../../common/os/home-directory-path.injectable";
|
||||
import { testUsingFakeTime } from "../../../common/test-utils/use-fake-time";
|
||||
import type { ClusterId } from "../../../common/cluster-types";
|
||||
import getClusterByIdInjectable from "../../../common/cluster-store/get-by-id.injectable";
|
||||
import createClusterInjectable from "../../../main/create-cluster/create-cluster.injectable";
|
||||
import { onLoadOfApplicationInjectionToken } from "../../../main/start-main-application/runnable-tokens/on-load-of-application-injection-token";
|
||||
import currentLocationInjectable from "../../api/current-location.injectable";
|
||||
import lensProxyPortInjectable from "../../../main/lens-proxy/lens-proxy-port.injectable";
|
||||
|
||||
type Callback = (di: DiContainer) => void | Promise<void>;
|
||||
|
||||
@ -265,11 +267,14 @@ export const getApplicationBuilder = () => {
|
||||
|
||||
const render = renderFor(windowDi);
|
||||
|
||||
rendered = render(
|
||||
<Router history={history}>
|
||||
<environment.RootComponent />
|
||||
</Router>,
|
||||
);
|
||||
rendered = render((
|
||||
<>
|
||||
<div id="terminal-init" />
|
||||
<Router history={history}>
|
||||
<environment.RootComponent />
|
||||
</Router>
|
||||
</>
|
||||
));
|
||||
},
|
||||
|
||||
send: (arg) => {
|
||||
@ -289,11 +294,11 @@ export const getApplicationBuilder = () => {
|
||||
const namespaces = observable.set<string>();
|
||||
const namespaceItems = observable.array<Namespace>();
|
||||
const selectedNamespaces = observable.set<string>();
|
||||
const clusters = observable.map<ClusterId, Cluster>();
|
||||
const clusterId = "some-cluster-id";
|
||||
const startMainApplication = mainDi.inject(startMainApplicationInjectable);
|
||||
|
||||
const startApplication = async ({ shouldStartHidden }: { shouldStartHidden: boolean }) => {
|
||||
mainDi.inject(lensProxyPortInjectable).set(42);
|
||||
|
||||
for (const callback of beforeApplicationStartCallbacks) {
|
||||
await callback(mainDi);
|
||||
}
|
||||
@ -308,6 +313,41 @@ export const getApplicationBuilder = () => {
|
||||
applicationHasStarted = true;
|
||||
};
|
||||
|
||||
mainDi.override(getClusterByIdInjectable, () => (id) => clusters.get(id));
|
||||
|
||||
beforeWindowStartCallbacks.push((windowDi) => windowDi.override(getClusterByIdInjectable, () => (id) => clusters.get(id)));
|
||||
beforeWindowStartCallbacks.push((windowDi) => windowDi.override(currentLocationInjectable, () => {
|
||||
const port = mainDi.inject(lensProxyPortInjectable);
|
||||
|
||||
return {
|
||||
hostname: "localhost",
|
||||
port: `${port.get()}`,
|
||||
protocol: "http",
|
||||
};
|
||||
}));
|
||||
|
||||
runInAction(() => {
|
||||
mainDi.register(getInjectable({
|
||||
id: "create-fake-cluster",
|
||||
instantiate: (di) => ({
|
||||
id: "create-fake-cluster",
|
||||
run: () => {
|
||||
const createCluster = di.inject(createClusterInjectable);
|
||||
const cluster = createCluster({
|
||||
contextName: "some-context-name",
|
||||
id: clusterId,
|
||||
kubeConfigPath: "/some-kube-config-path",
|
||||
}, {
|
||||
clusterServerUrl: "https://some-url.com:8797",
|
||||
});
|
||||
|
||||
clusters.set(clusterId, cluster);
|
||||
},
|
||||
}),
|
||||
injectionToken: onLoadOfApplicationInjectionToken,
|
||||
}));
|
||||
});
|
||||
|
||||
const builder: ApplicationBuilder = {
|
||||
mainDi,
|
||||
applicationWindow: {
|
||||
@ -501,18 +541,7 @@ export const getApplicationBuilder = () => {
|
||||
environment = environments.clusterFrame;
|
||||
|
||||
builder.beforeWindowStart((windowDi) => {
|
||||
const clusterStub = {
|
||||
id: "some-cluster-id",
|
||||
accessibleNamespaces: observable.array(),
|
||||
shouldShowResource: (kind) => allowedResourcesState.has(formatKubeApiResource(kind)),
|
||||
} as Partial<Cluster> as Cluster;
|
||||
|
||||
windowDi.override(activeKubernetesClusterInjectable, () =>
|
||||
computed(() => catalogEntityFromCluster(clusterStub)),
|
||||
);
|
||||
|
||||
windowDi.override(hostedClusterIdInjectable, () => clusterStub.id);
|
||||
windowDi.override(hostedClusterInjectable, () => clusterStub);
|
||||
windowDi.override(hostedClusterIdInjectable, () => clusterId);
|
||||
|
||||
// TODO: Figure out a way to remove this stub.
|
||||
windowDi.override(namespaceStoreInjectable, () => ({
|
||||
|
||||
@ -9,7 +9,6 @@ import { createContainer, isInjectable, getInjectable } from "@ogre-tools/inject
|
||||
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||
import requestFromChannelInjectable from "./utils/channel/request-from-channel.injectable";
|
||||
import { getOverrideFsWithFakes } from "../test-utils/override-fs-with-fakes";
|
||||
import terminalSpawningPoolInjectable from "./components/dock/terminal/terminal-spawning-pool.injectable";
|
||||
import hostedClusterIdInjectable from "./cluster-frame-context/hosted-cluster-id.injectable";
|
||||
import { runInAction } from "mobx";
|
||||
import requestAnimationFrameInjectable from "./components/animate/request-animation-frame.injectable";
|
||||
@ -70,7 +69,6 @@ export const getDiForUnitTesting = (
|
||||
}));
|
||||
});
|
||||
|
||||
di.override(terminalSpawningPoolInjectable, () => document.createElement("div"));
|
||||
di.override(hostedClusterIdInjectable, () => undefined);
|
||||
|
||||
di.override(legacyOnChannelListenInjectable, () => () => noop);
|
||||
|
||||
@ -3,9 +3,13 @@
|
||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||
*/
|
||||
import { getInjectable } from "@ogre-tools/injectable";
|
||||
import type { ChannelRequest, ChannelResponse, RequestChannel } from "../../../common/utils/channel/request-channel";
|
||||
import ipcRendererInjectable from "./ipc-renderer.injectable";
|
||||
import type { RequestFromChannel } from "../../../common/utils/channel/request-from-channel-injection-token";
|
||||
import { requestFromChannelInjectionToken } from "../../../common/utils/channel/request-from-channel-injection-token";
|
||||
|
||||
export interface RequestFromChannel {
|
||||
<Channel extends RequestChannel<void, unknown>>(channel: Channel): Promise<ChannelResponse<Channel>>;
|
||||
<Channel extends RequestChannel<unknown, unknown>>(channel: Channel, request: ChannelRequest<Channel>): Promise<ChannelResponse<Channel>>;
|
||||
}
|
||||
|
||||
const requestFromChannelInjectable = getInjectable({
|
||||
id: "request-from-channel",
|
||||
@ -15,8 +19,6 @@ const requestFromChannelInjectable = getInjectable({
|
||||
|
||||
return ((channel, request) => ipcRenderer.invoke(channel.id, request)) as RequestFromChannel;
|
||||
},
|
||||
|
||||
injectionToken: requestFromChannelInjectionToken,
|
||||
});
|
||||
|
||||
export default requestFromChannelInjectable;
|
||||
|
||||
@ -6,10 +6,10 @@ import { getInjectable } from "@ogre-tools/injectable";
|
||||
import { beforeFrameStartsSecondInjectionToken } from "../../before-frame-starts/tokens";
|
||||
import { syncBoxInitialValueChannel } from "../../../common/utils/sync-box/channels";
|
||||
import createSyncBoxStateInjectable from "../../../common/utils/sync-box/sync-box-state.injectable";
|
||||
import { requestFromChannelInjectionToken } from "../../../common/utils/channel/request-from-channel-injection-token";
|
||||
import { runInAction } from "mobx";
|
||||
import { syncBoxInjectionToken } from "../../../common/utils/sync-box/sync-box-injection-token";
|
||||
import assert from "assert";
|
||||
import requestFromChannelInjectable from "../channel/request-from-channel.injectable";
|
||||
|
||||
const provideInitialValuesForSyncBoxesInjectable = getInjectable({
|
||||
id: "provide-initial-values-for-sync-boxes",
|
||||
@ -17,7 +17,7 @@ const provideInitialValuesForSyncBoxesInjectable = getInjectable({
|
||||
instantiate: (di) => ({
|
||||
id: "provide-initial-values-for-sync-boxes",
|
||||
run: async () => {
|
||||
const requestFromChannel = di.inject(requestFromChannelInjectionToken);
|
||||
const requestFromChannel = di.inject(requestFromChannelInjectable);
|
||||
const syncBoxes = di.injectMany(syncBoxInjectionToken);
|
||||
const initialValues = await requestFromChannel(syncBoxInitialValueChannel);
|
||||
|
||||
@ -25,7 +25,7 @@ const provideInitialValuesForSyncBoxesInjectable = getInjectable({
|
||||
for (const { id, value } of initialValues) {
|
||||
const syncBox = syncBoxes.find((box) => box.id === id);
|
||||
|
||||
assert(syncBox);
|
||||
assert(syncBox, `Missing synx box with id="${id}"`);
|
||||
di.inject(createSyncBoxStateInjectable, syncBox.id).set(value);
|
||||
}
|
||||
});
|
||||
|
||||
@ -4,10 +4,10 @@
|
||||
*/
|
||||
import type { DiContainer } from "@ogre-tools/injectable";
|
||||
import { deserialize, serialize } from "v8";
|
||||
import type { RequestChannel } from "../../common/utils/channel/request-channel-listener-injection-token";
|
||||
import type { RequestFromChannel } from "../../common/utils/channel/request-from-channel-injection-token";
|
||||
import type { RequestChannel } from "../../common/utils/channel/request-channel";
|
||||
import enlistRequestChannelListenerInjectableInMain from "../../main/utils/channel/channel-listeners/enlist-request-channel-listener.injectable";
|
||||
import type { RequestChannelListener } from "../../main/utils/channel/channel-listeners/listener-tokens";
|
||||
import type { RequestFromChannel, RequestFromChannel } from "../../renderer/utils/channel/request-from-channel.injectable";
|
||||
import requestFromChannelInjectable from "../../renderer/utils/channel/request-from-channel.injectable";
|
||||
|
||||
export const overrideRequestingFromWindowToMain = (mainDi: DiContainer) => {
|
||||
|
||||
431
yarn.lock
431
yarn.lock
@ -1232,6 +1232,21 @@
|
||||
lodash "^4.17.15"
|
||||
tmp-promise "^3.0.2"
|
||||
|
||||
"@mapbox/node-pre-gyp@^1.0.0":
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c"
|
||||
integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==
|
||||
dependencies:
|
||||
detect-libc "^2.0.0"
|
||||
https-proxy-agent "^5.0.0"
|
||||
make-dir "^3.1.0"
|
||||
node-fetch "^2.6.7"
|
||||
nopt "^5.0.0"
|
||||
npmlog "^5.0.1"
|
||||
rimraf "^3.0.2"
|
||||
semver "^7.3.5"
|
||||
tar "^6.1.11"
|
||||
|
||||
"@material-ui/core@^4.12.3":
|
||||
version "4.12.4"
|
||||
resolved "https://registry.yarnpkg.com/@material-ui/core/-/core-4.12.4.tgz#4ac17488e8fcaf55eb6a7f5efb2a131e10138a73"
|
||||
@ -2252,6 +2267,15 @@
|
||||
dependencies:
|
||||
"@types/istanbul-lib-report" "*"
|
||||
|
||||
"@types/jest-image-snapshot@^5.1.0":
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest-image-snapshot/-/jest-image-snapshot-5.1.0.tgz#aa355ec40625fcb338fd31c935791bc8fde72bcf"
|
||||
integrity sha512-pfCz6dclA8mDxwXN/x/PuYBCPwzGuYcTfOVZvDAikC1GLXg/CwECF9UgtWse0tR42c6OaL7LPEnN7i/Dm86KkQ==
|
||||
dependencies:
|
||||
"@types/jest" "*"
|
||||
"@types/pixelmatch" "*"
|
||||
ssim.js "^3.1.1"
|
||||
|
||||
"@types/jest@*", "@types/jest@^28.1.6":
|
||||
version "28.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/jest/-/jest-28.1.6.tgz#d6a9cdd38967d2d746861fb5be6b120e38284dd4"
|
||||
@ -2379,6 +2403,13 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb"
|
||||
integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==
|
||||
|
||||
"@types/pixelmatch@*":
|
||||
version "5.2.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/pixelmatch/-/pixelmatch-5.2.4.tgz#ca145cc5ede1388c71c68edf2d1f5190e5ddd0f6"
|
||||
integrity sha512-HDaSHIAv9kwpMN7zlmwfTv6gax0PiporJOipcrGsVNF3Ba+kryOZc0Pio5pn6NhisgWr7TaajlPEKTbTAypIBQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/plist@^3.0.1":
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01"
|
||||
@ -2999,7 +3030,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
|
||||
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
|
||||
|
||||
abab@^2.0.3, abab@^2.0.5, abab@^2.0.6:
|
||||
abab@^2.0.5, abab@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291"
|
||||
integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==
|
||||
@ -3040,6 +3071,14 @@ acorn-globals@^6.0.0:
|
||||
acorn "^7.1.1"
|
||||
acorn-walk "^7.1.1"
|
||||
|
||||
acorn-globals@^7.0.0:
|
||||
version "7.0.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3"
|
||||
integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==
|
||||
dependencies:
|
||||
acorn "^8.1.0"
|
||||
acorn-walk "^8.0.2"
|
||||
|
||||
acorn-import-assertions@^1.7.6:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9"
|
||||
@ -3064,7 +3103,7 @@ acorn-walk@^7.0.0, acorn-walk@^7.1.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
|
||||
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
|
||||
|
||||
acorn-walk@^8.1.1:
|
||||
acorn-walk@^8.0.2, acorn-walk@^8.1.1:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
|
||||
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
|
||||
@ -3074,11 +3113,16 @@ acorn@^7.0.0, acorn@^7.1.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
|
||||
|
||||
acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0:
|
||||
acorn@^8.1.0, acorn@^8.8.0:
|
||||
version "8.8.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8"
|
||||
integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==
|
||||
|
||||
acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1:
|
||||
version "8.7.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30"
|
||||
integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==
|
||||
|
||||
adr@^1.4.3:
|
||||
version "1.4.3"
|
||||
resolved "https://registry.yarnpkg.com/adr/-/adr-1.4.3.tgz#2c817166da6c2d00183dc98cb55f1b5b32a3c482"
|
||||
@ -3299,6 +3343,14 @@ archy@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
|
||||
integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==
|
||||
|
||||
are-we-there-yet@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c"
|
||||
integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==
|
||||
dependencies:
|
||||
delegates "^1.0.0"
|
||||
readable-stream "^3.6.0"
|
||||
|
||||
are-we-there-yet@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d"
|
||||
@ -4023,6 +4075,15 @@ caniuse-lite@^1.0.30001332:
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001339.tgz#f9aece4ea8156071613b27791547ba0b33f176cf"
|
||||
integrity sha512-Es8PiVqCe+uXdms0Gu5xP5PF2bxLR7OBp3wUzUnuO7OHzhOfCyg3hdiGWVPVxhiuniOzng+hTc1u3fEQ0TlkSQ==
|
||||
|
||||
canvas@^2.10.1:
|
||||
version "2.10.1"
|
||||
resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.10.1.tgz#fbfd4b1b3b106c3454481d79d363ebadf8811c08"
|
||||
integrity sha512-29pIjn9uwTUsIgJUNd7GXxKk8sg4iyJwLm1wIilNIqX1mVzXSc2nUij9exW1LqNpis1d2ebMYfMqTWcokZ4pdA==
|
||||
dependencies:
|
||||
"@mapbox/node-pre-gyp" "^1.0.0"
|
||||
nan "^2.15.0"
|
||||
simple-get "^3.0.3"
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
@ -4316,7 +4377,7 @@ color-string@^1.6.0, color-string@^1.9.0:
|
||||
color-name "^1.0.0"
|
||||
simple-swizzle "^0.2.2"
|
||||
|
||||
color-support@^1.1.3:
|
||||
color-support@^1.1.2, color-support@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2"
|
||||
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
|
||||
@ -4521,7 +4582,7 @@ connect-history-api-fallback@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8"
|
||||
integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
|
||||
|
||||
console-control-strings@^1.1.0:
|
||||
console-control-strings@^1.0.0, console-control-strings@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
|
||||
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
|
||||
@ -4742,16 +4803,6 @@ cssesc@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
|
||||
|
||||
cssfontparser@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3"
|
||||
integrity sha1-9AIvyPlwDGgCnVQghK+69CWj8+M=
|
||||
|
||||
cssom@^0.4.4:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
|
||||
integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==
|
||||
|
||||
cssom@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36"
|
||||
@ -4791,16 +4842,7 @@ data-uri-to-buffer@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b"
|
||||
integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==
|
||||
|
||||
data-urls@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
|
||||
integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==
|
||||
dependencies:
|
||||
abab "^2.0.3"
|
||||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^8.0.0"
|
||||
|
||||
data-urls@^3.0.1:
|
||||
data-urls@^3.0.1, data-urls@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143"
|
||||
integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==
|
||||
@ -4861,12 +4903,22 @@ debuglog@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
||||
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
|
||||
|
||||
decimal.js@^10.2.1, decimal.js@^10.3.1:
|
||||
decimal.js@^10.3.1:
|
||||
version "10.3.1"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783"
|
||||
integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
|
||||
|
||||
decode-uri-component@^0.2.0, decode-uri-component@^0.2.2:
|
||||
decimal.js@^10.4.1:
|
||||
version "10.4.2"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.2.tgz#0341651d1d997d86065a2ce3a441fbd0d8e8b98e"
|
||||
integrity sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==
|
||||
|
||||
decode-uri-component@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
|
||||
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
|
||||
|
||||
decode-uri-component@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9"
|
||||
integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==
|
||||
@ -4878,6 +4930,13 @@ decompress-response@^3.3.0:
|
||||
dependencies:
|
||||
mimic-response "^1.0.0"
|
||||
|
||||
decompress-response@^4.2.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986"
|
||||
integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==
|
||||
dependencies:
|
||||
mimic-response "^2.0.0"
|
||||
|
||||
decompress-response@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
|
||||
@ -5214,13 +5273,6 @@ domelementtype@^2.0.1, domelementtype@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
|
||||
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
|
||||
|
||||
domexception@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
|
||||
integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==
|
||||
dependencies:
|
||||
webidl-conversions "^5.0.0"
|
||||
|
||||
domexception@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673"
|
||||
@ -5496,6 +5548,11 @@ entities@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||
|
||||
entities@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174"
|
||||
integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==
|
||||
|
||||
env-paths@^2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
|
||||
@ -6584,15 +6641,6 @@ form-data@^2.5.0:
|
||||
combined-stream "^1.0.6"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f"
|
||||
integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
|
||||
@ -6711,6 +6759,21 @@ functions-have-names@^1.2.2:
|
||||
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
|
||||
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
|
||||
|
||||
gauge@^3.0.0:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395"
|
||||
integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==
|
||||
dependencies:
|
||||
aproba "^1.0.3 || ^2.0.0"
|
||||
color-support "^1.1.2"
|
||||
console-control-strings "^1.0.0"
|
||||
has-unicode "^2.0.1"
|
||||
object-assign "^4.1.1"
|
||||
signal-exit "^3.0.0"
|
||||
string-width "^4.2.3"
|
||||
strip-ansi "^6.0.1"
|
||||
wide-align "^1.1.2"
|
||||
|
||||
gauge@^4.0.3:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce"
|
||||
@ -6772,6 +6835,11 @@ get-proxy@^2.0.0:
|
||||
dependencies:
|
||||
npm-conf "^1.1.0"
|
||||
|
||||
get-stdin@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398"
|
||||
integrity sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==
|
||||
|
||||
get-stream@3.0.0, get-stream@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
|
||||
@ -6945,6 +7013,11 @@ globrex@^0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
|
||||
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
|
||||
|
||||
glur@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glur/-/glur-1.1.2.tgz#f20ea36db103bfc292343921f1f91e83c3467689"
|
||||
integrity sha512-l+8esYHTKOx2G/Aao4lEQ0bnHWg4fWtJbVoZZT9Knxi01pB8C80BR85nONLFwkkQoFRCmXY+BUcGZN3yZ2QsRA==
|
||||
|
||||
got@^11.8.6:
|
||||
version "11.8.6"
|
||||
resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a"
|
||||
@ -7202,13 +7275,6 @@ hpagent@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/hpagent/-/hpagent-1.2.0.tgz#0ae417895430eb3770c03443456b8d90ca464903"
|
||||
integrity sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==
|
||||
|
||||
html-encoding-sniffer@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
|
||||
integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==
|
||||
dependencies:
|
||||
whatwg-encoding "^1.0.5"
|
||||
|
||||
html-encoding-sniffer@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9"
|
||||
@ -7356,7 +7422,7 @@ http2-wrapper@^1.0.0-beta.5.2:
|
||||
quick-lru "^5.1.1"
|
||||
resolve-alpn "^1.0.0"
|
||||
|
||||
https-proxy-agent@^5.0.0:
|
||||
https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"
|
||||
integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==
|
||||
@ -8040,14 +8106,6 @@ jake@^10.8.5:
|
||||
filelist "^1.0.1"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
jest-canvas-mock@^2.3.1:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-canvas-mock/-/jest-canvas-mock-2.4.0.tgz#947b71442d7719f8e055decaecdb334809465341"
|
||||
integrity sha512-mmMpZzpmLzn5vepIaHk5HoH3Ka4WykbSoLuG/EKoJd0x0ID/t+INo1l8ByfcUJuDM+RIsL4QDg/gDnBbrj2/IQ==
|
||||
dependencies:
|
||||
cssfontparser "^1.2.1"
|
||||
moo-color "^1.0.2"
|
||||
|
||||
jest-changed-files@^28.1.3:
|
||||
version "28.1.3"
|
||||
resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831"
|
||||
@ -8205,6 +8263,21 @@ jest-haste-map@^28.1.3:
|
||||
optionalDependencies:
|
||||
fsevents "^2.3.2"
|
||||
|
||||
jest-image-snapshot@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-image-snapshot/-/jest-image-snapshot-5.2.0.tgz#4af046935b465f0460aa73e890717bbc25d431e9"
|
||||
integrity sha512-msKQqsxr4ZS8S3FQ6ot1SPlDKc4pCfyKY3SxU9LEoASj1zoEfglDYjmxNX53pxpNf7Fp7CJZvwP4xkNXVQgEXA==
|
||||
dependencies:
|
||||
chalk "^1.1.3"
|
||||
get-stdin "^5.0.1"
|
||||
glur "^1.1.2"
|
||||
lodash "^4.17.4"
|
||||
mkdirp "^0.5.1"
|
||||
pixelmatch "^5.1.0"
|
||||
pngjs "^3.4.0"
|
||||
rimraf "^2.6.2"
|
||||
ssim.js "^3.1.1"
|
||||
|
||||
jest-leak-detector@^28.1.3:
|
||||
version "28.1.3"
|
||||
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d"
|
||||
@ -8487,39 +8560,6 @@ jsbn@~0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
|
||||
|
||||
jsdom@^16.7.0:
|
||||
version "16.7.0"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
|
||||
integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==
|
||||
dependencies:
|
||||
abab "^2.0.5"
|
||||
acorn "^8.2.4"
|
||||
acorn-globals "^6.0.0"
|
||||
cssom "^0.4.4"
|
||||
cssstyle "^2.3.0"
|
||||
data-urls "^2.0.0"
|
||||
decimal.js "^10.2.1"
|
||||
domexception "^2.0.1"
|
||||
escodegen "^2.0.0"
|
||||
form-data "^3.0.0"
|
||||
html-encoding-sniffer "^2.0.1"
|
||||
http-proxy-agent "^4.0.1"
|
||||
https-proxy-agent "^5.0.0"
|
||||
is-potential-custom-element-name "^1.0.1"
|
||||
nwsapi "^2.2.0"
|
||||
parse5 "6.0.1"
|
||||
saxes "^5.0.1"
|
||||
symbol-tree "^3.2.4"
|
||||
tough-cookie "^4.0.0"
|
||||
w3c-hr-time "^1.0.2"
|
||||
w3c-xmlserializer "^2.0.0"
|
||||
webidl-conversions "^6.1.0"
|
||||
whatwg-encoding "^1.0.5"
|
||||
whatwg-mimetype "^2.3.0"
|
||||
whatwg-url "^8.5.0"
|
||||
ws "^7.4.6"
|
||||
xml-name-validator "^3.0.0"
|
||||
|
||||
jsdom@^19.0.0:
|
||||
version "19.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-19.0.0.tgz#93e67c149fe26816d38a849ea30ac93677e16b6a"
|
||||
@ -8553,6 +8593,38 @@ jsdom@^19.0.0:
|
||||
ws "^8.2.3"
|
||||
xml-name-validator "^4.0.0"
|
||||
|
||||
jsdom@^20.0.1:
|
||||
version "20.0.1"
|
||||
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.1.tgz#d95b4a3b6e1eec6520aa01d9d908eade8c6ba153"
|
||||
integrity sha512-pksjj7Rqoa+wdpkKcLzQRHhJCEE42qQhl/xLMUKHgoSejaKOdaXEAnqs6uDNwMl/fciHTzKeR8Wm8cw7N+g98A==
|
||||
dependencies:
|
||||
abab "^2.0.6"
|
||||
acorn "^8.8.0"
|
||||
acorn-globals "^7.0.0"
|
||||
cssom "^0.5.0"
|
||||
cssstyle "^2.3.0"
|
||||
data-urls "^3.0.2"
|
||||
decimal.js "^10.4.1"
|
||||
domexception "^4.0.0"
|
||||
escodegen "^2.0.0"
|
||||
form-data "^4.0.0"
|
||||
html-encoding-sniffer "^3.0.0"
|
||||
http-proxy-agent "^5.0.0"
|
||||
https-proxy-agent "^5.0.1"
|
||||
is-potential-custom-element-name "^1.0.1"
|
||||
nwsapi "^2.2.2"
|
||||
parse5 "^7.1.1"
|
||||
saxes "^6.0.0"
|
||||
symbol-tree "^3.2.4"
|
||||
tough-cookie "^4.1.2"
|
||||
w3c-xmlserializer "^3.0.0"
|
||||
webidl-conversions "^7.0.0"
|
||||
whatwg-encoding "^2.0.0"
|
||||
whatwg-mimetype "^3.0.0"
|
||||
whatwg-url "^11.0.0"
|
||||
ws "^8.9.0"
|
||||
xml-name-validator "^4.0.0"
|
||||
|
||||
jsesc@^2.5.1:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
|
||||
@ -9116,7 +9188,7 @@ lodash.templatesettings@^4.0.0:
|
||||
dependencies:
|
||||
lodash._reinterpolate "^3.0.0"
|
||||
|
||||
lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
|
||||
lodash@^4.17.10, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
@ -9450,6 +9522,11 @@ mimic-response@^1.0.0, mimic-response@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
|
||||
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
|
||||
|
||||
mimic-response@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
|
||||
integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
|
||||
|
||||
mimic-response@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9"
|
||||
@ -9674,13 +9751,6 @@ monaco-editor@^0.29.1:
|
||||
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.29.1.tgz#6ee93d8a5320704d48fd7058204deed72429c020"
|
||||
integrity sha512-rguaEG/zrPQSaKzQB7IfX/PpNa0qxF1FY8ZXRkN4WIl8qZdTQRSRJCtRto7IMcSgrU6H53RXI+fTcywOBC4aVw==
|
||||
|
||||
moo-color@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/moo-color/-/moo-color-1.0.3.tgz#d56435f8359c8284d83ac58016df7427febece74"
|
||||
integrity sha512-i/+ZKXMDf6aqYtBhuOcej71YSlbjT3wCO/4H1j8rPvxDJEifdwgg5MaFyu6iYAT8GBZJg2z0dkgK4YMzvURALQ==
|
||||
dependencies:
|
||||
color-name "^1.1.4"
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
@ -9714,6 +9784,11 @@ nan@^2.14.0:
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
|
||||
integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
|
||||
|
||||
nan@^2.15.0:
|
||||
version "2.17.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
|
||||
integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==
|
||||
|
||||
nanoid@^3.3.4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
|
||||
@ -9793,6 +9868,13 @@ node-domexception@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5"
|
||||
integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==
|
||||
|
||||
node-fetch@^2.6.7:
|
||||
version "2.6.7"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
|
||||
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-fetch@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.0.tgz#37e71db4ecc257057af828d523a7243d651d91e4"
|
||||
@ -10136,6 +10218,16 @@ npm@^8.19.3:
|
||||
which "^2.0.2"
|
||||
write-file-atomic "^4.0.1"
|
||||
|
||||
npmlog@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0"
|
||||
integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==
|
||||
dependencies:
|
||||
are-we-there-yet "^2.0.0"
|
||||
console-control-strings "^1.1.0"
|
||||
gauge "^3.0.0"
|
||||
set-blocking "^2.0.0"
|
||||
|
||||
npmlog@^6.0.0, npmlog@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830"
|
||||
@ -10158,6 +10250,11 @@ nwsapi@^2.2.0:
|
||||
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
|
||||
integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==
|
||||
|
||||
nwsapi@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0"
|
||||
integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==
|
||||
|
||||
oauth-sign@~0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
|
||||
@ -10565,6 +10662,13 @@ parse5@6.0.1:
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
||||
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
|
||||
|
||||
parse5@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.1.tgz#4649f940ccfb95d8754f37f73078ea20afe0c746"
|
||||
integrity sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==
|
||||
dependencies:
|
||||
entities "^4.4.0"
|
||||
|
||||
parseurl@~1.3.2, parseurl@~1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
||||
@ -10691,6 +10795,13 @@ pirates@^4.0.4:
|
||||
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b"
|
||||
integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==
|
||||
|
||||
pixelmatch@^5.1.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-5.3.0.tgz#5e5321a7abedfb7962d60dbf345deda87cb9560a"
|
||||
integrity sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==
|
||||
dependencies:
|
||||
pngjs "^6.0.0"
|
||||
|
||||
pkg-dir@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
|
||||
@ -10725,6 +10836,16 @@ plist@^3.0.1, plist@^3.0.4:
|
||||
base64-js "^1.5.1"
|
||||
xmlbuilder "^9.0.7"
|
||||
|
||||
pngjs@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
|
||||
integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
|
||||
|
||||
pngjs@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821"
|
||||
integrity sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==
|
||||
|
||||
popper.js@1.16.1-lts:
|
||||
version "1.16.1-lts"
|
||||
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05"
|
||||
@ -11685,6 +11806,13 @@ rfc6902@^5.0.1:
|
||||
resolved "https://registry.yarnpkg.com/rfc6902/-/rfc6902-5.0.1.tgz#e16f18dc322c755d6dd948423ddf52bb451eca3d"
|
||||
integrity sha512-tYGfLpKIq9X7lrt4o3IkD9w9bpeAtsejfAqWNR98AoxfTsZqCepKa8eDlRiX8QMiCOD9vMx0/YbKLx0G1nPi5w==
|
||||
|
||||
rimraf@^2.6.2:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
rimraf@^3.0.0, rimraf@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
|
||||
@ -11795,6 +11923,13 @@ saxes@^5.0.1:
|
||||
dependencies:
|
||||
xmlchars "^2.2.0"
|
||||
|
||||
saxes@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5"
|
||||
integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==
|
||||
dependencies:
|
||||
xmlchars "^2.2.0"
|
||||
|
||||
scheduler@^0.20.2:
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
|
||||
@ -12073,6 +12208,15 @@ simple-concat@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
|
||||
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
|
||||
|
||||
simple-get@^3.0.3:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55"
|
||||
integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==
|
||||
dependencies:
|
||||
decompress-response "^4.2.0"
|
||||
once "^1.3.1"
|
||||
simple-concat "^1.0.0"
|
||||
|
||||
simple-get@^4.0.0, simple-get@^4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543"
|
||||
@ -12338,6 +12482,11 @@ sshpk@^1.7.0:
|
||||
safer-buffer "^2.0.2"
|
||||
tweetnacl "~0.14.0"
|
||||
|
||||
ssim.js@^3.1.1:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/ssim.js/-/ssim.js-3.5.0.tgz#d7276b9ee99b57a5ff0db34035f02f35197e62df"
|
||||
integrity sha512-Aj6Jl2z6oDmgYFFbQqK7fght19bXdOxY7Tj03nF+03M9gCBAjeIiO8/PlEGMfKDwYpw4q6iBqVq2YuREorGg/g==
|
||||
|
||||
ssri@^8.0.0, ssri@^8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af"
|
||||
@ -12968,12 +13117,15 @@ tough-cookie@^4.0.0:
|
||||
punycode "^2.1.1"
|
||||
universalify "^0.1.2"
|
||||
|
||||
tr46@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240"
|
||||
integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==
|
||||
tough-cookie@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.2.tgz#e53e84b85f24e0b65dd526f46628db6c85f6b874"
|
||||
integrity sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==
|
||||
dependencies:
|
||||
psl "^1.1.33"
|
||||
punycode "^2.1.1"
|
||||
universalify "^0.2.0"
|
||||
url-parse "^1.5.3"
|
||||
|
||||
tr46@^3.0.0:
|
||||
version "3.0.0"
|
||||
@ -12982,6 +13134,11 @@ tr46@^3.0.0:
|
||||
dependencies:
|
||||
punycode "^2.1.1"
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
||||
|
||||
traverse-chain@~0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/traverse-chain/-/traverse-chain-0.1.0.tgz#61dbc2d53b69ff6091a12a168fd7d433107e40f1"
|
||||
@ -13299,6 +13456,11 @@ universalify@^0.1.0, universalify@^0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||
|
||||
universalify@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
|
||||
integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==
|
||||
|
||||
universalify@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
|
||||
@ -13337,7 +13499,7 @@ url-parse-lax@^3.0.0:
|
||||
dependencies:
|
||||
prepend-http "^2.0.0"
|
||||
|
||||
url-parse@^1.5.10:
|
||||
url-parse@^1.5.10, url-parse@^1.5.3:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
|
||||
integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
|
||||
@ -13464,13 +13626,6 @@ w3c-hr-time@^1.0.2:
|
||||
dependencies:
|
||||
browser-process-hrtime "^1.0.0"
|
||||
|
||||
w3c-xmlserializer@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"
|
||||
integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==
|
||||
dependencies:
|
||||
xml-name-validator "^3.0.0"
|
||||
|
||||
w3c-xmlserializer@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz#06cdc3eefb7e4d0b20a560a5a3aeb0d2d9a65923"
|
||||
@ -13534,15 +13689,10 @@ web-streams-polyfill@^3.0.3:
|
||||
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
|
||||
integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
|
||||
|
||||
webidl-conversions@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
|
||||
integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==
|
||||
|
||||
webidl-conversions@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
|
||||
integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
|
||||
|
||||
webidl-conversions@^7.0.0:
|
||||
version "7.0.0"
|
||||
@ -13683,13 +13833,6 @@ websocket-extensions@>=0.1.1:
|
||||
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
|
||||
integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
|
||||
|
||||
whatwg-encoding@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
|
||||
integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
|
||||
dependencies:
|
||||
iconv-lite "0.4.24"
|
||||
|
||||
whatwg-encoding@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53"
|
||||
@ -13697,11 +13840,6 @@ whatwg-encoding@^2.0.0:
|
||||
dependencies:
|
||||
iconv-lite "0.6.3"
|
||||
|
||||
whatwg-mimetype@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
|
||||
integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
|
||||
|
||||
whatwg-mimetype@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7"
|
||||
@ -13723,14 +13861,13 @@ whatwg-url@^11.0.0:
|
||||
tr46 "^3.0.0"
|
||||
webidl-conversions "^7.0.0"
|
||||
|
||||
whatwg-url@^8.0.0, whatwg-url@^8.5.0:
|
||||
version "8.7.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
|
||||
integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
|
||||
dependencies:
|
||||
lodash "^4.7.0"
|
||||
tr46 "^2.1.0"
|
||||
webidl-conversions "^6.1.0"
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
which-boxed-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
@ -13757,7 +13894,7 @@ which@^2.0.1, which@^2.0.2:
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
wide-align@^1.1.5:
|
||||
wide-align@^1.1.2, wide-align@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3"
|
||||
integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==
|
||||
@ -13845,20 +13982,20 @@ write-file-atomic@^4.0.0, write-file-atomic@^4.0.1:
|
||||
imurmurhash "^0.1.4"
|
||||
signal-exit "^3.0.7"
|
||||
|
||||
ws@^7.3.1, ws@^7.4.6:
|
||||
ws@^7.3.1:
|
||||
version "7.5.7"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67"
|
||||
integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
|
||||
|
||||
ws@^8.12.0, ws@^8.2.3, ws@^8.4.2:
|
||||
ws@^8.12.0:
|
||||
version "8.12.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.0.tgz#485074cc392689da78e1828a9ff23585e06cddd8"
|
||||
integrity sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==
|
||||
|
||||
xml-name-validator@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
||||
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
|
||||
ws@^8.2.3, ws@^8.4.2, ws@^8.9.0:
|
||||
version "8.11.0"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"
|
||||
integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==
|
||||
|
||||
xml-name-validator@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user