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

Merge branch 'master' into electron-13.4.0

This commit is contained in:
Jari Kolehmainen 2021-09-27 07:37:45 +03:00
commit cb80998a5b
42 changed files with 335 additions and 270 deletions

View File

@ -15,7 +15,7 @@ trigger: none
jobs: jobs:
- job: Linux - job: Linux
pool: pool:
vmImage: ubuntu-16.04 vmImage: ubuntu-18.04
strategy: strategy:
matrix: matrix:
kube_1.16: kube_1.16:
@ -46,7 +46,7 @@ jobs:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube sudo install minikube-linux-amd64 /usr/local/bin/minikube
sudo minikube start --driver=none --kubernetes-version $(kubernetes_version) sudo minikube start --driver=none --kubernetes-version $(kubernetes_version)
# Although the kube and minikube config files are in placed $HOME they are owned by root sudo mv /root/.kube /root/.minikube $HOME
sudo chown -R $USER $HOME/.kube $HOME/.minikube sudo chown -R $USER $HOME/.kube $HOME/.minikube
displayName: Install integration test dependencies displayName: Install integration test dependencies
- script: make node_modules - script: make node_modules

View File

@ -109,7 +109,7 @@ jobs:
- job: Linux - job: Linux
pool: pool:
vmImage: ubuntu-16.04 vmImage: ubuntu-18.04
strategy: strategy:
matrix: matrix:
node_14.x: node_14.x:

View File

@ -2,7 +2,7 @@ name: Test
on: on:
pull_request: pull_request:
branches: branches:
- "*" - "**"
push: push:
branches: branches:
- master - master
@ -12,7 +12,7 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
os: [ubuntu-16.04, macos-11, windows-2019] os: [ubuntu-18.04, macos-11, windows-2019]
node-version: [14.x] node-version: [14.x]
steps: steps:
- name: Checkout Release from lens - name: Checkout Release from lens
@ -67,15 +67,9 @@ jobs:
- run: make test-extensions - run: make test-extensions
name: Run In-tree Extension tests name: Run In-tree Extension tests
- run: | - name: Install integration test dependencies
sudo apt-get update id: minikube
sudo apt-get install libgconf-2-4 conntrack -y uses: medyagh/setup-minikube@5a9a7104d7322fa40424de8855c84685e89cefd7
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
sudo minikube start --driver=none
# Although the kube and minikube config files are in placed $HOME they are owned by root
sudo chown -R $USER $HOME/.kube $HOME/.minikube
name: Install integration test dependencies
if: runner.os == 'Linux' if: runner.os == 'Linux'
- run: xvfb-run --auto-servernum --server-args='-screen 0, 1600x900x24' make integration - run: xvfb-run --auto-servernum --server-args='-screen 0, 1600x900x24' make integration

View File

@ -2,7 +2,9 @@
Lens releases are built by CICD automatically on git tags. The typical release process flow is the following: Lens releases are built by CICD automatically on git tags. The typical release process flow is the following:
1. From a clean and up to date `master` run `make release-version <version-type>` where `<version-type>` is one of the following: 1. If doing a patch release checkout the `release/vMAJOR.MINOR` branch for the appropriate `MAJOR`/`MINOR` version and manually `cherry-pick` the PRs required for the patch that were commited to master. If there are any conflicts they must be resolved manually. If necessary, get assistance from the PR authors.
1. From a clean and up to date `master` (or `release/vMAJOR.MINOR` if doing a patch release) run `make release-version <version-type>` where `<version-type>` is one of the following:
- `major` - `major`
- `minor` - `minor`
- `patch` - `patch`
@ -17,15 +19,15 @@ Lens releases are built by CICD automatically on git tags. The typical release p
- `rc` - `rc`
This assumes origin is set to https://github.com/lensapp/lens.git. If not then set GIT_REMOTE to the remote that is set to https://github.com/lensapp/lens.git. For example run `GIT_REMOTE=upstream make release-version ...` This assumes origin is set to https://github.com/lensapp/lens.git. If not then set GIT_REMOTE to the remote that is set to https://github.com/lensapp/lens.git. For example run `GIT_REMOTE=upstream make release-version ...`
1. Open the PR (git should have printed a link to GitHub in the console) with the contents of all the accepted PRs since the last release. The PR description needs to be filled with the draft release description. From https://github.com/lensapp/lens click on Releases, the draft release should be first in the list, click `Edit` and copy/paste the markdown to the PR description. Add the `skip-changelog` label and click `Create Pull Request`. 1. Open the PR (git should have printed a link to GitHub in the console) with the contents of all the accepted PRs since the last release. The PR description needs to be filled with the draft release description. From https://github.com/lensapp/lens click on Releases, the draft release should be first in the list, click `Edit` and copy/paste the markdown to the PR description. Add the `skip-changelog` label and click `Create Pull Request`. If this is a patch release be sure to set the PR base branch to `release/vMAJOR.MINOR` instead of `master`.
1. After the PR is accepted and passes CI (and before merging), go to the same branch and run `make tag-release` (set GIT_REMOTE if necessary). This additionally runs the azure jobs to build the binaries and put them on S3. 1. After the PR is accepted and passes CI (and before merging), go to the same branch and run `make tag-release` (set GIT_REMOTE if necessary). This additionally triggers the azure jobs to build the binaries and put them on S3.
1. If the CI fails at this stage the problem needs to be fixed. Sometimes an azure job fails due to outside service issues (e.g. Apple signing occasionally fails), in which case the specific azure job can be rerun from https://dev.azure.com/lensapp/lensapp/_build. Otherwise changes to the codebase may need to be done and committed to the release branch and pushed to https://github.com/lensapp/lens. CI will run again. As well the release tag needs to be manually set to this new commit. You can do something like: 1. If the CI fails at this stage the problem needs to be fixed. Sometimes an azure job fails due to outside service issues (e.g. Apple signing occasionally fails), in which case the specific azure job can be rerun from https://dev.azure.com/lensapp/lensapp/_build. Otherwise changes to the codebase may need to be done and committed to the release branch and pushed to https://github.com/lensapp/lens. CI will run again. As well the release tag needs to be manually set to this new commit. You can do something like:
- `git push origin :refs/tags/vX.Y.Z-beta.N` (removes the tag from https://github.com/lensapp/lens) - `git push origin :refs/tags/vX.Y.Z-beta.N` (removes the tag from https://github.com/lensapp/lens)
- `git tag -fa vX.Y.Z-beta.N` (move the tag locally to the current commit) - `git tag -fa vX.Y.Z-beta.N` (move the tag locally to the current commit)
- `git push origin --tags` (update the tags on https://github.com/lensapp/lens to reflect this local change) - `git push origin --tags` (update the tags on https://github.com/lensapp/lens to reflect this local change)
1. Once CI passes again go to the releases tab on GitHub. You can use the existing draft release prepared by k8slens-bot (select the correct tag). Or you can create a new release from the tag that was created, and make sure that the change log is the same as that of the PR, and the title is the tag. Either way, click the prerelease checkbox if this is not a new major, minor, or patch version before clicking `Publish release`. 1. Once CI passes again go to the releases tab on GitHub. You can use the existing draft release prepared by k8slens-bot (select the correct tag). Or you can create a new release from the tag that was created, and make sure that the change log is the same as that of the PR, and the title is the tag. Either way, click the prerelease checkbox if this is not a new major, minor, or patch version before clicking `Publish release`.
1. Merge the release PR after the release is published. GitHub should delete the branch once it is merged. 1. Merge the release PR after the release is published. If it is a patch release then there is no need to squash the cherry-picked commits as part of the merge. GitHub should delete the branch once it is merged.
1. If you have just released a new major or minor version then create a new `release/vMAJOR.MINOR` branch from that same tag and push it to https://github.com/lensapp/lens. Given the commit of the merged release PR from the master branch you can do this like 1. If you have just released a new major or minor version then create a new `release/vMAJOR.MINOR` branch from that same tag and push it to https://github.com/lensapp/lens. Given the commit of the merged release PR from the master branch you can do this like
`git push origin <commit>:refs/heads/release/vX.Y` `git push origin <commit>:refs/heads/release/vX.Y`
@ -37,4 +39,4 @@ Other tasks
- generate a changelog from the prerelease descriptions (for major/minor releases) - generate a changelog from the prerelease descriptions (for major/minor releases)
- announce the release on lens and lens-hq slack channels (release is announced automatically on the community slack lens channel through the above publishing process) - announce the release on lens and lens-hq slack channels (release is announced automatically on the community slack lens channel through the above publishing process)
- announce on lens-hq that master is open for PR merges for the next release (for major/minor releases) - announce on lens-hq that master is open for PR merges for the next release (for major/minor releases)
- update issues on github (bump those that did not make it into the release to a subsequent release) (for major/minor releases) - update issues on github (bump those that did not make it into the release to a subsequent release) (for major/minor/patch releases)

View File

@ -6645,9 +6645,9 @@
} }
}, },
"tmpl": { "tmpl": {
"version": "1.0.4", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
"integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"dev": true "dev": true
}, },
"to-arraybuffer": { "to-arraybuffer": {

View File

@ -6608,9 +6608,9 @@
} }
}, },
"tmpl": { "tmpl": {
"version": "1.0.4", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
"integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"dev": true "dev": true
}, },
"to-arraybuffer": { "to-arraybuffer": {

View File

@ -6561,9 +6561,9 @@
} }
}, },
"tmpl": { "tmpl": {
"version": "1.0.4", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
"integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
"dev": true "dev": true
}, },
"to-arraybuffer": { "to-arraybuffer": {

View File

@ -216,14 +216,14 @@
"md5-file": "^5.0.0", "md5-file": "^5.0.0",
"mobx": "^6.3.0", "mobx": "^6.3.0",
"mobx-observable-history": "^2.0.1", "mobx-observable-history": "^2.0.1",
"mobx-react": "^7.1.0", "mobx-react": "^7.2.0",
"mock-fs": "^4.14.0", "mock-fs": "^4.14.0",
"moment": "^2.29.1", "moment": "^2.29.1",
"moment-timezone": "^0.5.33", "moment-timezone": "^0.5.33",
"monaco-editor": "^0.26.1", "monaco-editor": "^0.26.1",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"node-pty": "^0.10.1", "node-pty": "^0.10.1",
"npm": "^6.14.8", "npm": "^6.14.15",
"openid-client": "^3.15.2", "openid-client": "^3.15.2",
"p-limit": "^3.1.0", "p-limit": "^3.1.0",
"path-to-regexp": "^6.1.0", "path-to-regexp": "^6.1.0",
@ -348,7 +348,6 @@
"jest-canvas-mock": "^2.3.1", "jest-canvas-mock": "^2.3.1",
"jest-fetch-mock": "^3.0.3", "jest-fetch-mock": "^3.0.3",
"jest-mock-extended": "^1.0.16", "jest-mock-extended": "^1.0.16",
"json-to-pretty-yaml": "^1.2.2",
"make-plural": "^6.2.2", "make-plural": "^6.2.2",
"mini-css-extract-plugin": "^1.6.0", "mini-css-extract-plugin": "^1.6.0",
"node-gyp": "7.1.2", "node-gyp": "7.1.2",
@ -368,7 +367,7 @@
"react-select-event": "^5.1.0", "react-select-event": "^5.1.0",
"react-table": "^7.7.0", "react-table": "^7.7.0",
"react-window": "^1.8.5", "react-window": "^1.8.5",
"sass": "^1.39.0", "sass": "^1.41.1",
"sass-loader": "^8.0.2", "sass-loader": "^8.0.2",
"sharp": "^0.29.0", "sharp": "^0.29.0",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",

View File

@ -51,6 +51,7 @@ export interface KubernetesClusterSpec extends CatalogEntitySpec {
material?: string; material?: string;
background?: string; background?: string;
}; };
accessibleNamespaces?: string[];
} }
export interface KubernetesClusterMetadata extends CatalogEntityMetadata { export interface KubernetesClusterMetadata extends CatalogEntityMetadata {

View File

@ -57,6 +57,10 @@ export class WebLink extends CatalogEntity<CatalogEntityMetadata, WebLinkStatus,
} }
}); });
} }
catalogCategoryRegistry
.getCategoryForEntity<WebLinkCategory>(this)
?.emit("contextMenuOpen", this, context);
} }
} }

View File

@ -159,7 +159,7 @@ export abstract class KubeObjectStore<T extends KubeObject> extends ItemStore<T>
this.loadedNamespaces = namespaces; this.loadedNamespaces = namespaces;
return Promise // load resources per namespace return Promise // load resources per namespace
.all(namespaces.map(namespace => api.list({ namespace, reqInit }))) .all(namespaces.map(namespace => api.list({ namespace, reqInit }, this.query)))
.then(items => items.flat().filter(Boolean)); .then(items => items.flat().filter(Boolean));
} }
} }

View File

@ -59,24 +59,24 @@ if (ipcMain) {
), ),
}) })
); );
if (!isTestEnv) {
transports.push(
new winston.transports.File({
handleExceptions: false,
level: logLevel,
filename: "lens.log",
dirname: getPath("logs"),
maxsize: 16 * 1024,
maxFiles: 16,
tailable: true,
})
);
}
} else { } else {
transports.push(new BrowserConsole()); transports.push(new BrowserConsole());
} }
if (!isTestEnv) {
transports.push(
new winston.transports.File({
handleExceptions: false,
level: logLevel,
filename: "lens.log",
dirname: getPath("logs"),
maxsize: 16 * 1024,
maxFiles: 16,
tailable: true,
})
);
}
export default winston.createLogger({ export default winston.createLogger({
format: format.simple(), format: format.simple(),
transports, transports,

View File

@ -25,7 +25,7 @@ import { Singleton } from "../../common/utils";
import { LensExtension } from "../lens-extension"; import { LensExtension } from "../lens-extension";
export class BaseRegistry<T, I = T> extends Singleton { export class BaseRegistry<T, I = T> extends Singleton {
private items = observable.map<T, I>([], {deep: false}); private items = observable.map<T, I>([], { deep: false });
constructor() { constructor() {
super(); super();

View File

@ -25,9 +25,9 @@ import { BaseRegistry } from "./base-registry";
import type { LensExtension } from "../lens-extension"; import type { LensExtension } from "../lens-extension";
import type { CatalogEntity } from "../../common/catalog"; import type { CatalogEntity } from "../../common/catalog";
export type CommandContext = { export interface CommandContext {
entity?: CatalogEntity; entity?: CatalogEntity;
}; }
export interface CommandRegistration { export interface CommandRegistration {
id: string; id: string;

View File

@ -193,7 +193,10 @@ export class ClusterManager extends Singleton {
} else { } else {
cluster.kubeConfigPath = entity.spec.kubeconfigPath; cluster.kubeConfigPath = entity.spec.kubeconfigPath;
cluster.contextName = entity.spec.kubeconfigContext; cluster.contextName = entity.spec.kubeconfigContext;
cluster.accessibleNamespaces = entity.spec.accessibleNamespaces ?? [];
if (entity.spec.accessibleNamespace) {
cluster.accessibleNamespaces = entity.spec.accessibleNamespaces;
}
this.updateEntityFromCluster(cluster); this.updateEntityFromCluster(cluster);
} }

View File

@ -275,7 +275,7 @@ export class Kubectl {
return false; return false;
}); });
isValid = !await this.checkBinary(this.path, false); isValid = await this.checkBinary(this.path, false);
} }
if (!isValid) { if (!isValid) {

View File

@ -31,7 +31,6 @@ import { IpcRendererNavigationEvents } from "../renderer/navigation/events";
import logger from "./logger"; import logger from "./logger";
import { productName } from "../common/vars"; import { productName } from "../common/vars";
import { LensProxy } from "./lens-proxy"; import { LensProxy } from "./lens-proxy";
import * as path from "path";
function isHideable(window: BrowserWindow | null): boolean { function isHideable(window: BrowserWindow | null): boolean {
return Boolean(window && !window.isDestroyed()); return Boolean(window && !window.isDestroyed());
@ -85,7 +84,6 @@ export class WindowManager extends Singleton {
titleBarStyle: "hiddenInset", titleBarStyle: "hiddenInset",
backgroundColor: "#1e2124", backgroundColor: "#1e2124",
webPreferences: { webPreferences: {
preload: path.join(__static, "build", "preload.js"),
nodeIntegration: true, nodeIntegration: true,
nodeIntegrationInSubFrames: true, nodeIntegrationInSubFrames: true,
enableRemoteModule: true, enableRemoteModule: true,

View File

@ -31,7 +31,7 @@ import { once } from "lodash";
export type EntityFilter = (entity: CatalogEntity) => any; export type EntityFilter = (entity: CatalogEntity) => any;
export class CatalogEntityRegistry { export class CatalogEntityRegistry {
@observable.ref activeEntity: CatalogEntity; @observable protected activeEntityId: string | undefined = undefined;
protected _entities = observable.map<string, CatalogEntity>([], { deep: true }); protected _entities = observable.map<string, CatalogEntity>([], { deep: true });
protected filters = observable.set<EntityFilter>([], { protected filters = observable.set<EntityFilter>([], {
deep: false, deep: false,
@ -46,6 +46,22 @@ export class CatalogEntityRegistry {
makeObservable(this); makeObservable(this);
} }
get activeEntity(): CatalogEntity | null {
return this._entities.get(this.activeEntityId) || null;
}
set activeEntity(raw: CatalogEntity | string | null) {
if (raw) {
const id = typeof raw === "string"
? raw
: raw.getId();
this.activeEntityId = id;
} else {
this.activeEntityId = undefined;
}
}
init() { init() {
ipcRendererOn("catalog:items", (event, items: (CatalogEntityData & CatalogEntityKindData)[]) => { ipcRendererOn("catalog:items", (event, items: (CatalogEntityData & CatalogEntityKindData)[]) => {
this.updateItems(items); this.updateItems(items);

View File

@ -58,7 +58,6 @@ export class TerminalApi extends WebSocketApi {
public onReady = new EventEmitter<[]>(); public onReady = new EventEmitter<[]>();
@observable public isReady = false; @observable public isReady = false;
@observable public shellRunCommandsFinished = false;
public readonly url: string; public readonly url: string;
constructor(protected options: TerminalApiQuery) { constructor(protected options: TerminalApiQuery) {
@ -92,7 +91,6 @@ export class TerminalApi extends WebSocketApi {
connect() { connect() {
this.emitStatus("Connecting ..."); this.emitStatus("Connecting ...");
this.onData.addListener(this._onReady, { prepend: true }); this.onData.addListener(this._onReady, { prepend: true });
this.onData.addListener(this._onShellRunCommandsFinished);
super.connect(this.url); super.connect(this.url);
} }
@ -109,24 +107,6 @@ export class TerminalApi extends WebSocketApi {
this.onReady.removeAllListeners(); this.onReady.removeAllListeners();
} }
_onShellRunCommandsFinished = (data: string) => {
if (!data) {
return;
}
/**
* This is a heuistic for ditermining when a shell has finished executing
* its own rc file (or RunCommands file) such as `.bashrc` or `.zshrc`.
*
* This heuistic assumes that the prompt line of a terminal is a single line
* and ends with a whitespace character.
*/
if (data.match(/\r?\n/) === null && data.match(/\s$/)) {
this.shellRunCommandsFinished = true;
this.onData.removeListener(this._onShellRunCommandsFinished);
}
};
@boundMethod @boundMethod
protected _onReady(data: string) { protected _onReady(data: string) {
if (!data) return true; if (!data) return true;

View File

@ -62,7 +62,7 @@ export class AddCluster extends React.Component {
@observable kubeContexts = observable.map<string, Option>(); @observable kubeContexts = observable.map<string, Option>();
@observable customConfig = ""; @observable customConfig = "";
@observable isWaiting = false; @observable isWaiting = false;
@observable errorText: string; @observable errors: string[] = [];
constructor(props: {}) { constructor(props: {}) {
super(props); super(props);
@ -75,7 +75,7 @@ export class AddCluster extends React.Component {
@computed get allErrors(): string[] { @computed get allErrors(): string[] {
return [ return [
this.errorText, ...this.errors,
...iter.map(this.kubeContexts.values(), ({ error }) => error) ...iter.map(this.kubeContexts.values(), ({ error }) => error)
].filter(Boolean); ].filter(Boolean);
} }
@ -85,7 +85,14 @@ export class AddCluster extends React.Component {
const { config, error } = loadConfigFromString(this.customConfig.trim() || "{}"); const { config, error } = loadConfigFromString(this.customConfig.trim() || "{}");
this.kubeContexts.replace(getContexts(config)); this.kubeContexts.replace(getContexts(config));
this.errorText = error?.toString();
if (error) {
this.errors.push(error.toString());
}
if (config.contexts.length === 0) {
this.errors.push('No contexts defined, either missing the "contexts" field, or it is empty.');
}
}, 500); }, 500);
@action @action
@ -124,7 +131,7 @@ export class AddCluster extends React.Component {
value={this.customConfig} value={this.customConfig}
onChange={value => { onChange={value => {
this.customConfig = value; this.customConfig = value;
this.errorText = ""; this.errors.length = 0;
this.refreshContexts(); this.refreshContexts();
}} }}
/> />

View File

@ -55,6 +55,14 @@ export class HelmCharts extends Component<Props> {
return helmChartStore.getByName(chartName, repo); return helmChartStore.getByName(chartName, repo);
} }
onDetails = (chart: HelmChart) => {
if (chart === this.selectedChart) {
this.hideDetails();
} else {
this.showDetails(chart);
}
};
showDetails = (chart: HelmChart) => { showDetails = (chart: HelmChart) => {
if (!chart) { if (!chart) {
navigation.push(helmChartsURL()); navigation.push(helmChartsURL());
@ -121,7 +129,7 @@ export class HelmCharts extends Component<Props> {
{ className: "menu" } { className: "menu" }
]} ]}
detailsItem={this.selectedChart} detailsItem={this.selectedChart}
onDetails={this.showDetails} onDetails={this.onDetails}
/> />
{this.selectedChart && ( {this.selectedChart && (
<HelmChartDetails <HelmChartDetails

View File

@ -75,6 +75,14 @@ export class HelmReleases extends Component<Props> {
}); });
} }
onDetails = (item: HelmRelease) => {
if (item === this.selectedRelease) {
this.hideDetails();
} else {
this.showDetails(item);
}
};
showDetails = (item: HelmRelease) => { showDetails = (item: HelmRelease) => {
navigation.push(releaseURL({ navigation.push(releaseURL({
params: { params: {
@ -169,7 +177,7 @@ export class HelmReleases extends Component<Props> {
message: this.renderRemoveDialogMessage(selectedItems) message: this.renderRemoveDialogMessage(selectedItems)
})} })}
detailsItem={this.selectedRelease} detailsItem={this.selectedRelease}
onDetails={this.showDetails} onDetails={this.onDetails}
/> />
<ReleaseDetails <ReleaseDetails
release={this.selectedRelease} release={this.selectedRelease}

View File

@ -122,7 +122,11 @@ export class Catalog extends React.Component<Props> {
} }
onDetails = (item: CatalogEntityItem<CatalogEntity>) => { onDetails = (item: CatalogEntityItem<CatalogEntity>) => {
this.catalogEntityStore.selectedItemId = item.getId(); if (this.catalogEntityStore.selectedItemId === item.getId()) {
this.catalogEntityStore.selectedItemId = null;
} else {
this.catalogEntityStore.selectedItemId = item.getId();
}
}; };
onMenuItemClick(menuItem: CatalogEntityContextMenu) { onMenuItemClick(menuItem: CatalogEntityContextMenu) {

View File

@ -33,7 +33,7 @@ import { boundMethod, cssNames, prevDefault } from "../../utils";
import type { ItemObject } from "../../../common/item.store"; import type { ItemObject } from "../../../common/item.store";
import { Spinner } from "../spinner"; import { Spinner } from "../spinner";
import { ThemeStore } from "../../theme.store"; import { ThemeStore } from "../../theme.store";
import { kubeSelectedUrlParam, showDetails } from "../kube-detail-params"; import { kubeSelectedUrlParam, toggleDetails } from "../kube-detail-params";
import { kubeWatchApi } from "../../../common/k8s-api/kube-watch-api"; import { kubeWatchApi } from "../../../common/k8s-api/kube-watch-api";
import { apiManager } from "../../../common/k8s-api/api-manager"; import { apiManager } from "../../../common/k8s-api/api-manager";
@ -124,7 +124,7 @@ export class ClusterIssues extends React.Component<Props> {
key={getId()} key={getId()}
sortItem={warning} sortItem={warning}
selected={selfLink === kubeSelectedUrlParam.get()} selected={selfLink === kubeSelectedUrlParam.get()}
onClick={prevDefault(() => showDetails(selfLink))} onClick={prevDefault(() => toggleDetails(selfLink))}
> >
<TableCell className="message"> <TableCell className="message">
{message} {message}

View File

@ -19,26 +19,12 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
.EntitySettings { .entityName {
$spacing: $padding * 3; @apply font-bold overflow-hidden;
word-break: break-word;
color: var(--textColorAccent);
// TODO: move sub-component styles to separate files display: -webkit-box;
.admin-note { /* Simulate text-overflow:ellipsis styles but for multiple text lines */
font-size: small; -webkit-line-clamp: 3;
opacity: 0.5; -webkit-box-orient: vertical;
margin-left: $margin; }
}
.button-area {
margin-top: $margin * 2;
}
.file-loader {
margin-top: $margin * 2;
}
.Input, .Select {
margin-top: $padding;
}
}

View File

@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import "./entity-settings.scss"; import styles from "./entity-settings.module.css";
import React from "react"; import React from "react";
import { observable, makeObservable } from "mobx"; import { observable, makeObservable } from "mobx";
@ -98,7 +98,9 @@ export class EntitySettings extends React.Component<Props> {
source={this.entity.metadata.source} source={this.entity.metadata.source}
src={this.entity.spec.icon?.src} src={this.entity.spec.icon?.src}
/> />
<h2>{this.entity.metadata.name}</h2> <div className={styles.entityName}>
{this.entity.metadata.name}
</div>
</div> </div>
<Tabs className="flex column" scrollable={false} onChange={this.onTabChange} value={this.activeTab}> <Tabs className="flex column" scrollable={false} onChange={this.onTabChange} value={this.activeTab}>
{ groups.map((group, groupIndex) => ( { groups.map((group, groupIndex) => (
@ -138,7 +140,6 @@ export class EntitySettings extends React.Component<Props> {
return ( return (
<SettingLayout <SettingLayout
className="CatalogEntitySettings"
navigation={this.renderNavigation()} navigation={this.renderNavigation()}
contentGaps={false} contentGaps={false}
> >

View File

@ -0,0 +1,58 @@
/**
* Copyright (c) 2021 OpenLens Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { computed } from "mobx";
import { observer } from "mobx-react";
import React from "react";
import { CatalogEntity, catalogEntityRunContext } from "../../api/catalog-entity";
import { catalogEntityRegistry } from "../../api/catalog-entity-registry";
import { CommandOverlay } from "../command-palette";
import { Select } from "../select";
@observer
export class ActivateEntityCommand extends React.Component {
@computed get options() {
return catalogEntityRegistry.items.map(entity => ({
label: `${entity.kind}: ${entity.getName()}`,
value: entity,
}));
}
onSelect(entity: CatalogEntity): void {
entity.onRun?.(catalogEntityRunContext);
CommandOverlay.close();
}
render() {
return (
<Select
menuPortalTarget={null}
onChange={(v) => this.onSelect(v.value)}
components={{ DropdownIndicator: null, IndicatorSeparator: null }}
menuIsOpen={true}
options={this.options}
autoFocus={true}
escapeClearsValue={false}
placeholder="Activate entity ..."
/>
);
}
}

View File

@ -0,0 +1,22 @@
/**
* Copyright (c) 2021 OpenLens Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
export * from "./activate-entity-command";

View File

@ -39,7 +39,6 @@
--font-weight-normal: 400; --font-weight-normal: 400;
--font-weight-bold: 500; --font-weight-bold: 500;
--main-layout-header: 40px; --main-layout-header: 40px;
--drag-region-height: 22px;
} }
*, *:before, *:after { *, *:before, *:after {
@ -105,7 +104,7 @@ html, body {
left: 0; left: 0;
top: 0; top: 0;
width: 100%; width: 100%;
height: var(--drag-region-height); height: var(--main-layout-header);
z-index: 1000; z-index: 1000;
pointer-events: none; pointer-events: none;
} }

View File

@ -19,7 +19,7 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import React from "react"; import React from "react";
import { observable, makeObservable, reaction } from "mobx"; import { observable, makeObservable } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react"; import { disposeOnUnmount, observer } from "mobx-react";
import { Redirect, Route, Router, Switch } from "react-router"; import { Redirect, Route, Router, Switch } from "react-router";
import { history } from "../navigation"; import { history } from "../navigation";
@ -97,13 +97,7 @@ export class App extends React.Component {
await cluster.whenReady; // cluster.activate() is done at this point await cluster.whenReady; // cluster.activate() is done at this point
const activeEntityDisposer = reaction(() => catalogEntityRegistry.getById(App.clusterId), (entity) => { catalogEntityRegistry.activeEntity = App.clusterId;
if (!entity) {
return;
}
catalogEntityRegistry.activeEntity = entity;
activeEntityDisposer();
}, {fireImmediately: true});
ExtensionLoader.getInstance().loadOnClusterRenderer(); ExtensionLoader.getInstance().loadOnClusterRenderer();
setTimeout(() => { setTimeout(() => {

View File

@ -19,25 +19,18 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import type { KubeConfig } from "@kubernetes/client-node"; import { dumpYaml, KubeConfig } from "@kubernetes/client-node";
import fs from "fs"; import fs from "fs";
import tempy from "tempy";
import * as lockFile from "proper-lockfile"; import * as lockFile from "proper-lockfile";
import YAML from "json-to-pretty-yaml";
import { noop } from "../../utils";
export async function saveKubeconfig(config: KubeConfig, path: string) { export async function saveKubeconfig(config: KubeConfig, path: string) {
const tmpFilePath = tempy.file();
try { try {
const release = await lockFile.lock(path); const release = await lockFile.lock(path);
const contents = YAML.stringify(JSON.parse(config.exportConfig())); const contents = dumpYaml(JSON.parse(config.exportConfig()));
await fs.promises.writeFile(tmpFilePath, contents); await fs.promises.writeFile(path, contents);
await fs.promises.rename(tmpFilePath, path); await release();
release();
} catch (e) { } catch (e) {
await fs.unlink(tmpFilePath, noop);
throw new Error(`Failed to acquire lock file.\n${e}`); throw new Error(`Failed to acquire lock file.\n${e}`);
} }
} }

View File

@ -117,15 +117,18 @@ export class TerminalStore extends Singleton {
await when(() => this.connections.has(tab.id)); await when(() => this.connections.has(tab.id));
const rcIsFinished = when(() => this.connections.get(tab.id).shellRunCommandsFinished); const shellIsReady = when(() => this.connections.get(tab.id).isReady);
const notifyVeryLong = setTimeout(() => { const notifyVeryLong = setTimeout(() => {
rcIsFinished.cancel(); shellIsReady.cancel();
Notifications.info("Terminal shell is taking a long time to complete startup. Please check your .rc file. Bypassing shell completion check.", { Notifications.info(
timeout: 4_000, "If terminal shell is not ready please check your shell init files, if applicable.",
}); {
timeout: 4_000,
},
);
}, 10_000); }, 10_000);
await rcIsFinished.catch(noop); await shellIsReady.catch(noop);
clearTimeout(notifyVeryLong); clearTimeout(notifyVeryLong);
} }

View File

@ -31,12 +31,20 @@
} }
.HotbarIcon { .HotbarIcon {
--iconActiveShadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px var(--textColorAccent);
--iconHoverShadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff50;
border-radius: 6px; border-radius: 6px;
user-select: none; user-select: none;
cursor: pointer; cursor: pointer;
transition: none; transition: none;
text-shadow: 0 0 4px #0000008f; text-shadow: 0 0 4px #0000008f;
position: relative; position: relative;
z-index: 0; // allows to catch state of :active pseudo-selector
&:active .MuiAvatar-root {
box-shadow: var(--iconActiveShadow) !important;
}
div.MuiAvatar-colorDefault { div.MuiAvatar-colorDefault {
font-weight:500; font-weight:500;
@ -64,20 +72,17 @@
box-shadow: none; box-shadow: none;
} }
div.MuiAvatar-root { .MuiAvatar-root {
width: var(--size); width: var(--size);
height: var(--size); height: var(--size);
border-radius: 6px;
&.active { &.active {
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px var(--textColorAccent); box-shadow: var(--iconActiveShadow);
} }
&.interactive { &.interactive:not(.active):hover {
&:hover { box-shadow: var(--iconHoverShadow);
&:not(.active) {
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff50;
}
}
} }
} }
@ -117,20 +122,6 @@
} }
} }
img {
border-radius: 6px;
&.active {
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px var(--textColorAccent);
}
&:hover {
&:not(.active) {
box-shadow: 0 0 0px 3px var(--clusterMenuBackground), 0 0 0px 6px #ffffff50;
}
}
}
.materialIcon { .materialIcon {
margin-left: 1px; margin-left: 1px;
margin-top: 1px; margin-top: 1px;

View File

@ -91,7 +91,7 @@ const defaultProps: Partial<InputProps> = {
export class Input extends React.Component<InputProps, State> { export class Input extends React.Component<InputProps, State> {
static defaultProps = defaultProps as object; static defaultProps = defaultProps as object;
public input: InputElement; public input: InputElement | null = null;
public validators: InputValidator[] = []; public validators: InputValidator[] = [];
public state: State = { public state: State = {
@ -191,7 +191,7 @@ export class Input extends React.Component<InputProps, State> {
} }
} }
this.input.setCustomValidity(errors.length ? errors[0].toString() : ""); this.input?.setCustomValidity(errors.length ? errors[0].toString() : "");
} }
setValidation(errors: React.ReactNode[]) { setValidation(errors: React.ReactNode[]) {

View File

@ -41,6 +41,16 @@ export const kubeSelectedUrlParam = createPageParam({
} }
}); });
export function toggleDetails(selfLink: string, resetSelected = true) {
const current = kubeSelectedUrlParam.get() === selfLink;
if (current) {
hideDetails();
} else {
showDetails(selfLink, resetSelected);
}
}
export function showDetails(selfLink = "", resetSelected = true) { export function showDetails(selfLink = "", resetSelected = true) {
const detailsUrl = getDetailsUrl(selfLink, resetSelected); const detailsUrl = getDetailsUrl(selfLink, resetSelected);

View File

@ -31,7 +31,7 @@ import { kubeWatchApi } from "../../../common/k8s-api/kube-watch-api";
import { clusterContext } from "../context"; import { clusterContext } from "../context";
import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter"; import { NamespaceSelectFilter } from "../+namespaces/namespace-select-filter";
import { ResourceKindMap, ResourceNames } from "../../utils/rbac"; import { ResourceKindMap, ResourceNames } from "../../utils/rbac";
import { kubeSelectedUrlParam, showDetails } from "../kube-detail-params"; import { kubeSelectedUrlParam, toggleDetails } from "../kube-detail-params";
export interface KubeObjectListLayoutProps<K extends KubeObject> extends ItemListLayoutProps<K> { export interface KubeObjectListLayoutProps<K extends KubeObject> extends ItemListLayoutProps<K> {
store: KubeObjectStore<K>; store: KubeObjectStore<K>;
@ -39,7 +39,7 @@ export interface KubeObjectListLayoutProps<K extends KubeObject> extends ItemLis
} }
const defaultProps: Partial<KubeObjectListLayoutProps<KubeObject>> = { const defaultProps: Partial<KubeObjectListLayoutProps<KubeObject>> = {
onDetails: (item: KubeObject) => showDetails(item.selfLink), onDetails: (item: KubeObject) => toggleDetails(item.selfLink),
}; };
@observer @observer

View File

@ -153,7 +153,7 @@ export function openServiceAccountKubeConfig(account: ServiceAccount) {
const namespace = account.getNs(); const namespace = account.getNs();
KubeConfigDialog.open({ KubeConfigDialog.open({
title: "{accountName} kubeconfig", title: `${accountName} kubeconfig`,
loader: () => apiBase.get(`/kubeconfig/service-account/${namespace}/${accountName}`) loader: () => apiBase.get(`/kubeconfig/service-account/${namespace}/${accountName}`)
}); });
} }

View File

@ -32,7 +32,7 @@ import { Storage } from "../+storage";
import { Network } from "../+network"; import { Network } from "../+network";
import { crdStore } from "../+custom-resources/crd.store"; import { crdStore } from "../+custom-resources/crd.store";
import { CustomResources } from "../+custom-resources/custom-resources"; import { CustomResources } from "../+custom-resources/custom-resources";
import { isActiveRoute } from "../../navigation"; import { isActiveRoute, navigate } from "../../navigation";
import { isAllowedResource } from "../../../common/utils/allowed-resource"; import { isAllowedResource } from "../../../common/utils/allowed-resource";
import { Spinner } from "../spinner"; import { Spinner } from "../spinner";
import { ClusterPageMenuRegistration, ClusterPageMenuRegistry, ClusterPageRegistry, getExtensionPageUrl } from "../../../extensions/registries"; import { ClusterPageMenuRegistration, ClusterPageMenuRegistry, ClusterPageRegistry, getExtensionPageUrl } from "../../../extensions/registries";
@ -110,7 +110,7 @@ export class Sidebar extends React.Component<Props> {
const routes: TabLayoutRoute[] = []; const routes: TabLayoutRoute[] = [];
const subMenus = ClusterPageMenuRegistry.getInstance().getSubItems(menu); const subMenus = ClusterPageMenuRegistry.getInstance().getSubItems(menu);
const clusterPageRegistry= ClusterPageRegistry.getInstance(); const clusterPageRegistry = ClusterPageRegistry.getInstance();
for (const subMenu of subMenus) { for (const subMenu of subMenus) {
const page = clusterPageRegistry.getByPageTarget(subMenu.target); const page = clusterPageRegistry.getByPageTarget(subMenu.target);
@ -193,6 +193,7 @@ export class Sidebar extends React.Component<Props> {
source={metadata.source} source={metadata.source}
src={spec.icon?.src} src={spec.icon?.src}
className="mr-5" className="mr-5"
onClick={() => navigate(routes.clusterURL())}
/> />
<div className={styles.clusterName}> <div className={styles.clusterName}>
{metadata.name} {metadata.name}

View File

@ -30,6 +30,7 @@ import { HotbarRemoveCommand } from "../components/hotbar/hotbar-remove-command"
import { HotbarSwitchCommand } from "../components/hotbar/hotbar-switch-command"; import { HotbarSwitchCommand } from "../components/hotbar/hotbar-switch-command";
import { navigate } from "../navigation"; import { navigate } from "../navigation";
import { HotbarRenameCommand } from "../components/hotbar/hotbar-rename-command"; import { HotbarRenameCommand } from "../components/hotbar/hotbar-rename-command";
import { ActivateEntityCommand } from "../components/activate-entity-command";
export function initCommandRegistry() { export function initCommandRegistry() {
CommandRegistry.getInstance() CommandRegistry.getInstance()
@ -196,5 +197,11 @@ export function initCommandRegistry() {
scope: "global", scope: "global",
action: () => CommandOverlay.open(<HotbarRenameCommand />) action: () => CommandOverlay.open(<HotbarRenameCommand />)
}, },
{
id: "catalog.searchEntities",
title: "Catalog: Activate Entity ...",
scope: "global",
action: () => CommandOverlay.open(<ActivateEntityCommand />)
},
]); ]);
} }

View File

@ -22,7 +22,7 @@
import path from "path"; import path from "path";
import type webpack from "webpack"; import type webpack from "webpack";
import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin"; import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin";
import { isProduction, mainDir, buildDir, isDevelopment, preloadEntrypoint } from "./src/common/vars"; import { isProduction, mainDir, buildDir, isDevelopment } from "./src/common/vars";
import nodeExternals from "webpack-node-externals"; import nodeExternals from "webpack-node-externals";
import ProgressBarPlugin from "progress-bar-webpack-plugin"; import ProgressBarPlugin from "progress-bar-webpack-plugin";
import * as vars from "./src/common/vars"; import * as vars from "./src/common/vars";
@ -68,41 +68,4 @@ configs.push((): webpack.Configuration => {
}; };
}); });
configs.push((): webpack.Configuration => {
console.info("WEBPACK:preload", vars);
return {
context: __dirname,
target: "electron-main",
mode: isProduction ? "production" : "development",
devtool: isProduction ? "source-map" : "cheap-eval-source-map",
cache: isDevelopment,
entry: {
main: path.resolve(preloadEntrypoint),
},
output: {
libraryTarget: "global",
path: buildDir,
filename: "preload.js"
},
resolve: {
extensions: [".json", ".js", ".ts"],
mainFields: ["main"]
},
module: {
rules: [
{
test: /\.node$/,
use: "node-loader"
},
getTSLoader(/\.ts$/)
]
},
plugins: [
new ProgressBarPlugin(),
new ForkTsCheckerPlugin(),
].filter(Boolean)
};
});
export default configs; export default configs;

View File

@ -79,6 +79,9 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura
".ts", ".tsx", ".ts", ".tsx",
] ]
}, },
externals: {
"node-fetch": "commonjs node-fetch"
},
optimization: { optimization: {
minimize: false minimize: false
}, },

142
yarn.lock
View File

@ -4683,7 +4683,7 @@ debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.6:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
debuglog@^1.0.1: debuglog@*, debuglog@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
@ -6411,7 +6411,7 @@ fs-extra@^9.0.0, fs-extra@^9.0.1:
jsonfile "^6.0.1" jsonfile "^6.0.1"
universalify "^2.0.0" universalify "^2.0.0"
fs-minipass@^1.2.5: fs-minipass@^1.2.7:
version "1.2.7" version "1.2.7"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7"
integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==
@ -6823,12 +6823,7 @@ got@^9.6.0:
to-readable-stream "^1.0.0" to-readable-stream "^1.0.0"
url-parse-lax "^3.0.0" url-parse-lax "^3.0.0"
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.2, graceful-fs@^4.2.4: graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4:
version "4.2.6"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.3:
version "4.2.8" version "4.2.8"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
@ -7397,7 +7392,7 @@ import-local@^3.0.2:
pkg-dir "^4.2.0" pkg-dir "^4.2.0"
resolve-cwd "^3.0.0" resolve-cwd "^3.0.0"
imurmurhash@^0.1.4: imurmurhash@*, imurmurhash@^0.1.4:
version "0.1.4" version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
@ -8628,14 +8623,6 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json-to-pretty-yaml@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz#f4cd0bd0a5e8fe1df25aaf5ba118b099fd992d5b"
integrity sha1-9M0L0KXo/h3yWq9boRiwmf2ZLVs=
dependencies:
remedial "^1.0.7"
remove-trailing-spaces "^1.0.6"
json3@^3.3.3: json3@^3.3.3:
version "3.3.3" version "3.3.3"
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
@ -9173,6 +9160,11 @@ lodash-es@^4.17.20:
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
lodash._baseindexof@*:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c"
integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=
lodash._baseuniq@~4.6.0: lodash._baseuniq@~4.6.0:
version "4.6.0" version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
@ -9181,11 +9173,33 @@ lodash._baseuniq@~4.6.0:
lodash._createset "~4.0.0" lodash._createset "~4.0.0"
lodash._root "~3.0.0" lodash._root "~3.0.0"
lodash._bindcallback@*:
version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4=
lodash._cacheindexof@*:
version "3.0.2"
resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92"
integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=
lodash._createcache@*:
version "3.1.2"
resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093"
integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=
dependencies:
lodash._getnative "^3.0.0"
lodash._createset@~4.0.0: lodash._createset@~4.0.0:
version "4.0.3" version "4.0.3"
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=
lodash._getnative@*, lodash._getnative@^3.0.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=
lodash._root@~3.0.0: lodash._root@~3.0.0:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
@ -9211,6 +9225,11 @@ lodash.isequal@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
lodash.restparam@*:
version "3.6.1"
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=
lodash.toarray@^4.4.0: lodash.toarray@^4.4.0:
version "4.4.0" version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
@ -9630,7 +9649,7 @@ minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minipass@^2.3.5, minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: minipass@^2.3.5, minipass@^2.6.0, minipass@^2.9.0:
version "2.9.0" version "2.9.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==
@ -9645,7 +9664,7 @@ minipass@^3.0.0:
dependencies: dependencies:
yallist "^4.0.0" yallist "^4.0.0"
minizlib@^1.2.1: minizlib@^1.3.3:
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==
@ -9694,7 +9713,7 @@ mkdirp@1.x, mkdirp@^1.0.3, mkdirp@~1.0.4:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.0: mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.4, mkdirp@^0.5.5, mkdirp@~0.5.0:
version "0.5.5" version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@ -9715,10 +9734,10 @@ mobx-react-lite@^3.2.0:
resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.2.0.tgz#331d7365a6b053378dfe9c087315b4e41c5df69f" resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-3.2.0.tgz#331d7365a6b053378dfe9c087315b4e41c5df69f"
integrity sha512-q5+UHIqYCOpBoFm/PElDuOhbcatvTllgRp3M1s+Hp5j0Z6XNgDbgqxawJ0ZAUEyKM8X1zs70PCuhAIzX1f4Q/g== integrity sha512-q5+UHIqYCOpBoFm/PElDuOhbcatvTllgRp3M1s+Hp5j0Z6XNgDbgqxawJ0ZAUEyKM8X1zs70PCuhAIzX1f4Q/g==
mobx-react@^7.1.0: mobx-react@^7.2.0:
version "7.1.0" version "7.2.0"
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-7.1.0.tgz#d947cada3cfad294b4b6f692e969c242b9c16eaf" resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-7.2.0.tgz#241e925e963bb83a31d269f65f9f379e37ecbaeb"
integrity sha512-DxvA6VXmnZ+N9f/UTtolWtdRnAAQY2iHWTSPLktfpj8NKlXUe4dabBAjuXrBcZUM8GjLWnxD1ZEjssXq1M0RAw== integrity sha512-KHUjZ3HBmZlNnPd1M82jcdVsQRDlfym38zJhZEs33VxyVQTvL77hODCArq6+C1P1k/6erEeo2R7rpE7ZeOL7dg==
dependencies: dependencies:
mobx-react-lite "^3.2.0" mobx-react-lite "^3.2.0"
@ -10222,10 +10241,10 @@ npm-user-validate@^1.0.1:
resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.1.tgz#31428fc5475fe8416023f178c0ab47935ad8c561" resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.1.tgz#31428fc5475fe8416023f178c0ab47935ad8c561"
integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw== integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==
npm@^6.14.8: npm@^6.14.15:
version "6.14.13" version "6.14.15"
resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.13.tgz#e88bcb6c48209869c40b5cedad8a1508e58e6f30" resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.15.tgz#97dd51af5b5d6225b611b40c5cb4d31da1d467fe"
integrity sha512-SRl4jJi0EBHY2xKuu98FLRMo3VhYQSA6otyLnjSEiHoSG/9shXCFNJy9tivpUJvtkN9s6VDdItHa5Rn+fNBzag== integrity sha512-dkcQc4n+DiJAMYG2haNAMyJbmuvevjXz+WC9dCUzodw8EovwTIc6CATSsTEplCY6c0jG4OshxFGFJsrnKJguWA==
dependencies: dependencies:
JSONStream "^1.3.5" JSONStream "^1.3.5"
abbrev "~1.1.1" abbrev "~1.1.1"
@ -10245,6 +10264,7 @@ npm@^6.14.8:
cmd-shim "^3.0.3" cmd-shim "^3.0.3"
columnify "~1.5.4" columnify "~1.5.4"
config-chain "^1.1.12" config-chain "^1.1.12"
debuglog "*"
detect-indent "~5.0.0" detect-indent "~5.0.0"
detect-newline "^2.1.0" detect-newline "^2.1.0"
dezalgo "~1.0.3" dezalgo "~1.0.3"
@ -10259,6 +10279,7 @@ npm@^6.14.8:
has-unicode "~2.0.1" has-unicode "~2.0.1"
hosted-git-info "^2.8.9" hosted-git-info "^2.8.9"
iferr "^1.0.2" iferr "^1.0.2"
imurmurhash "*"
infer-owner "^1.0.4" infer-owner "^1.0.4"
inflight "~1.0.6" inflight "~1.0.6"
inherits "^2.0.4" inherits "^2.0.4"
@ -10277,8 +10298,14 @@ npm@^6.14.8:
libnpx "^10.2.4" libnpx "^10.2.4"
lock-verify "^2.1.0" lock-verify "^2.1.0"
lockfile "^1.0.4" lockfile "^1.0.4"
lodash._baseindexof "*"
lodash._baseuniq "~4.6.0" lodash._baseuniq "~4.6.0"
lodash._bindcallback "*"
lodash._cacheindexof "*"
lodash._createcache "*"
lodash._getnative "*"
lodash.clonedeep "~4.5.0" lodash.clonedeep "~4.5.0"
lodash.restparam "*"
lodash.union "~4.6.0" lodash.union "~4.6.0"
lodash.uniq "~4.5.0" lodash.uniq "~4.5.0"
lodash.without "~4.4.0" lodash.without "~4.4.0"
@ -10328,7 +10355,7 @@ npm@^6.14.8:
sorted-union-stream "~2.1.3" sorted-union-stream "~2.1.3"
ssri "^6.0.2" ssri "^6.0.2"
stringify-package "^1.0.1" stringify-package "^1.0.1"
tar "^4.4.13" tar "^4.4.19"
text-table "~0.2.0" text-table "~0.2.0"
tiny-relative-date "^1.3.0" tiny-relative-date "^1.3.0"
uid-number "0.0.6" uid-number "0.0.6"
@ -12101,21 +12128,11 @@ relateurl@^0.2.7:
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
remedial@^1.0.7:
version "1.0.8"
resolved "https://registry.yarnpkg.com/remedial/-/remedial-1.0.8.tgz#a5e4fd52a0e4956adbaf62da63a5a46a78c578a0"
integrity sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==
remove-trailing-separator@^1.0.1: remove-trailing-separator@^1.0.1:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8=
remove-trailing-spaces@^1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz#4354d22f3236374702f58ee373168f6d6887ada7"
integrity sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==
renderkid@^2.0.1: renderkid@^2.0.1:
version "2.0.3" version "2.0.3"
resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149" resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.3.tgz#380179c2ff5ae1365c522bf2fcfcff01c5b74149"
@ -12381,7 +12398,7 @@ rxjs@^6.5.2:
dependencies: dependencies:
tslib "^1.9.0" tslib "^1.9.0"
safe-buffer@*, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: safe-buffer@*, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0:
version "5.2.1" version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@ -12436,17 +12453,10 @@ sass-loader@^8.0.2:
schema-utils "^2.6.1" schema-utils "^2.6.1"
semver "^6.3.0" semver "^6.3.0"
sass@^1.32.13: sass@^1.32.13, sass@^1.41.1:
version "1.35.2" version "1.41.1"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.35.2.tgz#b732314fcdaf7ef8d0f1698698adc378043cb821" resolved "https://registry.yarnpkg.com/sass/-/sass-1.41.1.tgz#bca5bed2154192779c29f48fca9c644c60c38d98"
integrity sha512-jhO5KAR+AMxCEwIH3v+4zbB2WB0z67V1X0jbapfVwQQdjHZUGUyukpnoM6+iCMfsIUC016w9OPKQ5jrNOS9uXw== integrity sha512-vIjX7izRxw3Wsiez7SX7D+j76v7tenfO18P59nonjr/nzCkZuoHuF7I/Fo0ZRZPKr88v29ivIdE9BqGDgQD/Nw==
dependencies:
chokidar ">=3.0.0 <4.0.0"
sass@^1.39.0:
version "1.39.0"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.39.0.tgz#6c64695d1c437767c8f1a4e471288e831f81d035"
integrity sha512-F4o+RhJkNOIG0b6QudYU8c78ZADKZjKDk5cyrf8XTKWfrgbtyVVXImFstJrc+1pkQDCggyidIOytq6gS4gCCZg==
dependencies: dependencies:
chokidar ">=3.0.0 <4.0.0" chokidar ">=3.0.0 <4.0.0"
@ -13521,18 +13531,18 @@ tar-stream@^2.1.4:
inherits "^2.0.3" inherits "^2.0.3"
readable-stream "^3.1.1" readable-stream "^3.1.1"
tar@^4.4.10, tar@^4.4.12, tar@^4.4.13: tar@^4.4.10, tar@^4.4.12, tar@^4.4.19:
version "4.4.13" version "4.4.19"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==
dependencies: dependencies:
chownr "^1.1.1" chownr "^1.1.4"
fs-minipass "^1.2.5" fs-minipass "^1.2.7"
minipass "^2.8.6" minipass "^2.9.0"
minizlib "^1.2.1" minizlib "^1.3.3"
mkdirp "^0.5.0" mkdirp "^0.5.5"
safe-buffer "^5.1.2" safe-buffer "^5.2.1"
yallist "^3.0.3" yallist "^3.1.1"
tar@^6.0.2, tar@^6.1.10: tar@^6.0.2, tar@^6.1.10:
version "6.1.10" version "6.1.10"
@ -13705,9 +13715,9 @@ tmp@^0.2.0, tmp@^0.2.1:
rimraf "^3.0.0" rimraf "^3.0.0"
tmpl@1.0.x: tmpl@1.0.x:
version "1.0.4" version "1.0.5"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==
to-arraybuffer@^1.0.0: to-arraybuffer@^1.0.0:
version "1.0.1" version "1.0.1"
@ -14924,7 +14934,7 @@ yallist@^2.1.2:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==