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

Merge branch 'master' into issue-3498

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2023-01-27 10:36:31 -05:00
commit 528384d2d9
106 changed files with 6261 additions and 1930 deletions

View File

@ -1,7 +1,8 @@
name: Check Documentation
on:
pull_request:
types: [opened, labeled, unlabeled, synchronize]
branches:
- "**"
jobs:
build:
name: Check Docs

View File

@ -32,4 +32,7 @@ jobs:
- name: Publish NPM package
run: |
npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
yarn lerna publish from-package --dist-tag master --no-push --no-git-tag-version --yes
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@ -37,6 +37,13 @@ jobs:
- name: Publish NPM packages
run: |
yarn lerna publish from-package --no-push --no-git-tag-version --yes
npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
DIST_TAG=$(cat lerna.json | jq '.version' --raw-output | xargs node ./packages/semver/dist/index.mjs --prerelease 0)
yarn lerna \
publish from-package \
--no-push \
--no-git-tag-version \
--yes \
--dist-tag ${DIST_TAG:-latest}
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@ -21,8 +21,9 @@ jobs:
- uses: butlerlogic/action-autotag@stable
id: tagger
with:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
tag_prefix: "v"
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
tag_prefix: v
root: /packages/core
- uses: ncipollo/release-action@v1
if: ${{ steps.tagger.outputs.tagname != '' }}
with:

View File

@ -53,15 +53,11 @@ jobs:
retry_on: error
command: yarn install --frozen-lockfile
- run: make test
- run: yarn run test:unit
name: Run tests
shell: bash
if: ${{ matrix.type == 'unit' }}
- run: make ci-validate-dev
if: ${{ contains(github.event.pull_request.labels.*.name, 'dependencies') && matrix.type == 'unit' }}
name: Validate dev mode will work
- name: Install integration test dependencies
id: minikube
uses: medyagh/setup-minikube@master

View File

@ -1,2 +1,3 @@
--install.check-files true
--install.network-timeout 100000
--install.network-timeout 100000
--publish.access public

View File

@ -1,31 +0,0 @@
CMD_ARGS = $(filter-out $@,$(MAKECMDGOALS))
%:
@:
ELECTRON_BUILDER_EXTRA_ARGS ?=
.PHONY: bootstrap
bootstrap:
yarn install
.PHONY: lint
lint: node_modules
yarn lint
.PHONY: test
test: node_modules
yarn run test:unit
.PHONY: integration
integration: build
yarn test:integration
.PHONY: build
build:
yarn lerna run build:app
.PHONY: clean
clean:
yarn run clean
yarn run clean:node_modules

View File

@ -4,6 +4,6 @@
"packages": [
"packages/*"
],
"version": "6.4.0-alpha.2",
"version": "6.4.0-beta.8",
"npmClient": "yarn"
}

18
nx.json
View File

@ -5,7 +5,8 @@
"options": {
"cacheableOperations": [
"build",
"prepare:dev"
"prepare:dev",
"prepare:lint"
]
}
}
@ -16,10 +17,25 @@
"^build"
]
},
"build:docs": {
"dependsOn": [
"^build"
]
},
"dev": {
"dependsOn": [
"prepare:dev"
]
},
"lint": {
"dependsOn": [
"^prepare:test"
]
},
"test:unit": {
"dependsOn": [
"^prepare:test"
]
}
}
}

View File

@ -11,7 +11,7 @@
"build:docs": "lerna run --stream build:docs",
"clean": "lerna run clean --stream",
"clean:node_modules": "lerna clean -y && rm -rf node_modules",
"dev": "lerna run dev --stream",
"dev": "lerna run dev --stream --skip-nx-cache",
"lint": "lerna run lint --stream",
"mkdocs:serve-local": "docker build -t mkdocs-serve-local:latest mkdocs/ && docker run --rm -it -p 8000:8000 -v ${PWD}:/docs mkdocs-serve-local:latest",
"mkdocs:verify": "docker build -t mkdocs-serve-local:latest mkdocs/ && docker run --rm -v ${PWD}:/docs mkdocs-serve-local:latest build --strict",
@ -24,6 +24,6 @@
},
"devDependencies": {
"adr": "^1.4.3",
"lerna": "^6.3.0"
"lerna": "^6.4.1"
}
}

View File

@ -1,9 +1,9 @@
{
"name": "@k8slens/open-lens",
"productName": "OpenLens",
"description": "OpenLens - Open Source IDE for Kubernetes",
"name": "@k8slens/core",
"productName": "",
"description": "Lens Desktop Core",
"homepage": "https://github.com/lensapp/lens",
"version": "6.4.0-alpha.4",
"version": "6.4.0-beta.8",
"repository": {
"type": "git",
"url": "git+https://github.com/lensapp/lens.git"
@ -12,6 +12,10 @@
"bugs": {
"url": "https://github.com/lensapp/lens/issues"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"main": "static/build/main.js",
"exports": {
"./main": "./static/build/library/main.js",
@ -33,25 +37,23 @@
}
},
"files": [
"build/download_binaries.ts",
"build/*.plist",
"build/installer.nsh",
"build/notarize.js",
"static/build/library/**/*",
"src/renderer/template.html",
"templates/**/*",
"types/*",
"tsconfig.json"
],
"copyright": "© 2022 OpenLens Authors",
"copyright": "© 2023 OpenLens Authors",
"license": "MIT",
"author": "OpenLens Authors <info@k8slens.dev>",
"scripts": {
"build": "env NODE_ENV=production yarn run webpack --config webpack/library-bundle.ts",
"clean": "rm -rf dist webpack/build/ static/build",
"compile:node-fetch": "yarn run webpack --config webpack/node-fetch.ts",
"clean": "rm -rf dist static/build",
"prepare:dev": "env NODE_ENV=development yarn run webpack --config webpack/library-bundle.ts --progress",
"dev": "env NODE_ENV=development yarn run webpack --config webpack/library-bundle.ts --watch",
"prepare": "yarn run compile:node-fetch",
"test:unit": "jest --testPathIgnorePatterns integration",
"test:watch": "func() { jest ${1} --watch --testPathIgnorePatterns integration; }; func",
"lint": "PROD=true yarn run eslint --ext js,ts,tsx --max-warnings=0 .",
@ -60,7 +62,7 @@
"config": {
"k8sProxyVersion": "0.3.0",
"bundledKubectlVersion": "1.23.3",
"bundledHelmVersion": "3.7.2",
"bundledHelmVersion": "3.11.0",
"sentryDsn": "",
"contentSecurityPolicy": "script-src 'unsafe-eval' 'self'; frame-src https://*.lens.app:*/; img-src * data:",
"welcomeRoute": "/welcome"
@ -95,6 +97,9 @@
"setupFilesAfterEnv": [
"<rootDir>/src/jest-after-env.setup.ts"
],
"transformIgnorePatterns": [
"node_modules/(?!jsonpath-plus)"
],
"runtime": "@side/jest-runtime"
},
"build": {},
@ -105,13 +110,11 @@
"^build"
],
"outputs": [
"{workspaceRoot}/build/webpack/",
"{workspaceRoot}/static/build/"
]
},
"dev": {
"outputs": [
"{workspaceRoot}/build/webpack/",
"{workspaceRoot}/static/build/"
]
}
@ -124,7 +127,8 @@
"@astronautlabs/jsonpath": "^1.1.0",
"@hapi/call": "^9.0.0",
"@hapi/subtext": "^7.0.4",
"@kubernetes/client-node": "^0.18.0",
"@k8slens/node-fetch": "^6.4.0-beta.8",
"@kubernetes/client-node": "^0.18.1",
"@material-ui/styles": "^4.11.5",
"@ogre-tools/fp": "^12.0.1",
"@ogre-tools/injectable": "^12.0.1",
@ -133,7 +137,7 @@
"@ogre-tools/injectable-react": "^12.0.1",
"@sentry/electron": "^3.0.8",
"@sentry/integrations": "^6.19.3",
"@side/jest-runtime": "^1.0.1",
"@side/jest-runtime": "^1.1.0",
"@testing-library/user-event": "^14.4.3",
"abort-controller": "^3.0.0",
"auto-bind": "^4.0.0",
@ -167,7 +171,6 @@
"mobx-utils": "^6.0.4",
"moment": "^2.29.4",
"moment-timezone": "^0.5.40",
"node-fetch": "^3.3.0",
"node-pty": "0.10.1",
"npm": "^8.19.3",
"p-limit": "^3.1.0",
@ -202,7 +205,7 @@
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@sentry/types": "^6.19.7",
"@swc/cli": "^0.1.59",
"@swc/core": "^1.3.27",
"@swc/core": "^1.3.28",
"@swc/jest": "^0.2.24",
"@testing-library/dom": "^7.31.2",
"@testing-library/jest-dom": "^5.16.5",
@ -211,7 +214,6 @@
"@types/byline": "^4.2.33",
"@types/chart.js": "^2.9.36",
"@types/circular-dependency-plugin": "5.0.5",
"@types/cli-progress": "^3.11.0",
"@types/color": "^3.0.3",
"@types/command-line-args": "^5.2.0",
"@types/crypto-js": "^3.1.47",
@ -219,7 +221,6 @@
"@types/electron-devtools-installer": "^2.2.1",
"@types/fs-extra": "^9.0.13",
"@types/glob-to-regexp": "^0.4.1",
"@types/gunzip-maybe": "^1.4.0",
"@types/hapi__call": "^9.0.0",
"@types/hapi__subtext": "^7.0.0",
"@types/html-webpack-plugin": "^3.2.6",
@ -248,7 +249,6 @@
"@types/semver": "^7.3.13",
"@types/sharp": "^0.31.1",
"@types/tar": "^6.1.3",
"@types/tar-stream": "^2.2.2",
"@types/tcp-port-used": "^1.0.1",
"@types/tempy": "^0.3.0",
"@types/triple-beam": "^1.3.2",
@ -258,14 +258,13 @@
"@types/webpack-dev-server": "^4.7.2",
"@types/webpack-env": "^1.18.0",
"@types/webpack-node-externals": "^2.5.3",
"@typescript-eslint/eslint-plugin": "^5.48.2",
"@typescript-eslint/parser": "^5.48.2",
"@typescript-eslint/eslint-plugin": "^5.49.0",
"@typescript-eslint/parser": "^5.49.0",
"adr": "^1.4.3",
"ansi_up": "^5.1.0",
"chalk": "^4.1.2",
"chart.js": "^2.9.4",
"circular-dependency-plugin": "^5.2.2",
"cli-progress": "^3.11.2",
"color": "^3.2.1",
"command-line-args": "^5.2.1",
"concurrently": "^7.6.0",
@ -284,8 +283,7 @@
"eslint-plugin-react": "^7.32.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-unused-imports": "^2.0.0",
"fork-ts-checker-webpack-plugin": "^6.5.2",
"gunzip-maybe": "^1.4.2",
"fork-ts-checker-webpack-plugin": "^7.3.0",
"html-webpack-plugin": "^5.5.0",
"identity-obj-proxy": "^3.0.0",
"ignore-loader": "^0.1.2",
@ -304,7 +302,7 @@
"node-gyp": "^8.3.0",
"node-loader": "^2.0.0",
"nodemon": "^2.0.20",
"playwright": "^1.29.2",
"playwright": "^1.30.0",
"postcss": "^8.4.21",
"postcss-loader": "^6.2.1",
"query-string": "^7.1.3",
@ -322,7 +320,6 @@
"sharp": "^0.31.3",
"style-loader": "^3.3.1",
"tailwindcss": "^3.2.4",
"tar-stream": "^2.2.0",
"ts-loader": "^9.4.2",
"ts-node": "^10.9.1",
"type-fest": "^2.14.0",

View File

@ -53,10 +53,16 @@ export abstract class BaseStore<T extends object> {
readonly displayName = kebabCase(this.params.configName).toUpperCase();
/**
* @ignore
*/
protected readonly dependencies: BaseStoreDependencies;
protected constructor(
protected readonly dependencies: BaseStoreDependencies,
dependencies: BaseStoreDependencies,
protected readonly params: BaseStoreParams<T>,
) {
this.dependencies = dependencies;
makeObservable(this);
}

View File

@ -7,7 +7,7 @@ import type { CatalogEntityMetadata, CatalogEntitySpec, CatalogEntityStatus } fr
import type { CatalogEntityActionContext } from "../catalog/catalog-entity";
import { CatalogCategory, CatalogEntity, categoryVersion } from "../catalog/catalog-entity";
interface GeneralEntitySpec extends CatalogEntitySpec {
export interface GeneralEntitySpec extends CatalogEntitySpec {
path: string;
icon?: {
material?: string;

View File

@ -9,7 +9,9 @@ import { observable, makeObservable } from "mobx";
import { once } from "lodash";
import type { Disposer } from "../utils";
import { iter } from "../utils";
import type { CategoryColumnRegistration } from "../../renderer/components/+catalog/custom-category-columns";
import type { CategoryColumnRegistration, TitleCellProps } from "../../renderer/components/+catalog/custom-category-columns";
export type { CategoryColumnRegistration, TitleCellProps };
export type CatalogEntityDataFor<Entity> = Entity extends CatalogEntity<infer Metadata, infer Status, infer Spec>
? CatalogEntityData<Metadata, Status, Spec>

View File

@ -157,7 +157,7 @@ export enum ClusterStatus {
*/
export interface KubeAuthUpdate {
message: string;
isError: boolean;
level: "info" | "warning" | "error";
}
/**

View File

@ -356,7 +356,7 @@ export class Cluster implements ClusterModel {
this.broadcastConnectUpdate("Starting connection ...");
await this.reconnect();
} catch (error) {
this.broadcastConnectUpdate(`Failed to start connection: ${error}`, true);
this.broadcastConnectUpdate(`Failed to start connection: ${error}`, "error");
return;
}
@ -366,7 +366,7 @@ export class Cluster implements ClusterModel {
this.broadcastConnectUpdate("Refreshing connection status ...");
await this.refreshConnectionStatus();
} catch (error) {
this.broadcastConnectUpdate(`Failed to connection status: ${error}`, true);
this.broadcastConnectUpdate(`Failed to connection status: ${error}`, "error");
return;
}
@ -376,7 +376,7 @@ export class Cluster implements ClusterModel {
this.broadcastConnectUpdate("Refreshing cluster accessibility ...");
await this.refreshAccessibility();
} catch (error) {
this.broadcastConnectUpdate(`Failed to refresh accessibility: ${error}`, true);
this.broadcastConnectUpdate(`Failed to refresh accessibility: ${error}`, "error");
return;
}
@ -484,9 +484,20 @@ export class Cluster implements ClusterModel {
resource: "*",
});
this.allowedNamespaces.replace(await this.requestAllowedNamespaces(proxyConfig));
this.knownResources.replace(await this.dependencies.requestApiResources(this));
const knownResources = await this.dependencies.requestApiResources(this);
if (knownResources.callWasSuccessful) {
this.knownResources.replace(knownResources.response);
} else if (this.knownResources.length > 0) {
this.dependencies.logger.warn(`[CLUSTER]: failed to list KUBE resources, sticking with previous list`);
} else {
this.dependencies.logger.warn(`[CLUSTER]: failed to list KUBE resources for the first time, blocking connection to cluster...`);
this.broadcastConnectUpdate("Failed to list kube API resources, please reconnect...", "error");
}
this.allowedResources.replace(await this.getAllowedResources(requestNamespaceListPermissions));
this.ready = true;
this.ready = this.knownResources.length > 0;
}
/**
@ -536,37 +547,37 @@ export class Cluster implements ClusterModel {
if (isRequestError(error)) {
if (error.statusCode) {
if (error.statusCode >= 400 && error.statusCode < 500) {
this.broadcastConnectUpdate("Invalid credentials", true);
this.broadcastConnectUpdate("Invalid credentials", "error");
return ClusterStatus.AccessDenied;
}
const message = String(error.error || error.message) || String(error);
this.broadcastConnectUpdate(message, true);
this.broadcastConnectUpdate(message, "error");
return ClusterStatus.Offline;
}
if (error.failed === true) {
if (error.timedOut === true) {
this.broadcastConnectUpdate("Connection timed out", true);
this.broadcastConnectUpdate("Connection timed out", "error");
return ClusterStatus.Offline;
}
this.broadcastConnectUpdate("Failed to fetch credentials", true);
this.broadcastConnectUpdate("Failed to fetch credentials", "error");
return ClusterStatus.AccessDenied;
}
const message = String(error.error || error.message) || String(error);
this.broadcastConnectUpdate(message, true);
this.broadcastConnectUpdate(message, "error");
} else if (error instanceof Error || typeof error === "string") {
this.broadcastConnectUpdate(`${error}`, true);
this.broadcastConnectUpdate(`${error}`, "error");
} else {
this.broadcastConnectUpdate("Unknown error has occurred", true);
this.broadcastConnectUpdate("Unknown error has occurred", "error");
}
return ClusterStatus.Offline;
@ -636,8 +647,8 @@ export class Cluster implements ClusterModel {
* broadcast an authentication update concerning this cluster
* @internal
*/
broadcastConnectUpdate(message: string, isError = false): void {
const update: KubeAuthUpdate = { message, isError };
broadcastConnectUpdate(message: string, level: KubeAuthUpdate["level"] = "info"): void {
const update: KubeAuthUpdate = { message, level };
this.dependencies.logger.debug(`[CLUSTER]: broadcasting connection update`, { ...update, meta: this.getMeta() });
this.dependencies.broadcastMessage(`cluster:${this.id}:connection-update`, update);
@ -668,7 +679,7 @@ export class Cluster implements ClusterModel {
}
protected async getAllowedResources(requestNamespaceListPermissions: RequestNamespaceListPermissions) {
if (!this.allowedNamespaces.length) {
if (!this.allowedNamespaces.length || !this.knownResources.length) {
return [];
}

View File

@ -5,23 +5,23 @@
// Custom event emitter
interface Options {
export interface EventEmitterOptions {
once?: boolean; // call once and remove
prepend?: boolean; // put listener to the beginning
}
type Callback<D extends [...any[]]> = (...data: D) => void | boolean;
export type EventEmitterCallback<D extends any[]> = (...data: D) => void | boolean;
export class EventEmitter<D extends [...any[]]> {
protected listeners: [Callback<D>, Options][] = [];
export class EventEmitter<D extends any[]> {
protected listeners: [EventEmitterCallback<D>, EventEmitterOptions][] = [];
addListener(callback: Callback<D>, options: Options = {}) {
addListener(callback: EventEmitterCallback<D>, options: EventEmitterOptions = {}) {
const fn = options.prepend ? "unshift" : "push";
this.listeners[fn]([callback, options]);
}
removeListener(callback: Callback<D>) {
removeListener(callback: EventEmitterCallback<D>) {
this.listeners = this.listeners.filter(([cb]) => cb !== callback);
}

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import type { RequestInit, Response } from "node-fetch";
import type { RequestInit, Response } from "@k8slens/node-fetch";
import type { AsyncResult } from "../utils/async-result";
import fetchInjectable from "./fetch.injectable";
@ -22,7 +22,6 @@ const downloadBinaryInjectable = getInjectable({
let result: Response;
try {
// TODO: upgrade node-fetch once we switch to ESM
result = await fetch(url, opts as RequestInit);
} catch (error) {
return {

View File

@ -4,7 +4,7 @@
*/
import type { AsyncResult } from "../../utils/async-result";
import type { Fetch } from "../fetch.injectable";
import type { RequestInit, Response } from "node-fetch";
import type { RequestInit, Response } from "@k8slens/node-fetch";
export interface DownloadJsonOptions {
signal?: AbortSignal | null | undefined;

View File

@ -1,19 +0,0 @@
/**
* 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 * as FetchModule from "node-fetch";
const { NodeFetch } = require("../../../build/webpack/node-fetch.bundle") as { NodeFetch: typeof FetchModule };
/**
* NOTE: while using this module can cause side effects, this specific injectable is not marked as
* such since sometimes the request can be wholely within the perview of unit test
*/
const nodeFetchModuleInjectable = getInjectable({
id: "node-fetch-module",
instantiate: () => NodeFetch,
});
export default nodeFetchModuleInjectable;

View File

@ -3,18 +3,14 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import type { RequestInit, Response } from "node-fetch";
import nodeFetchModuleInjectable from "./fetch-module.injectable";
import type { RequestInit, Response } from "@k8slens/node-fetch";
import fetch from "@k8slens/node-fetch";
export type Fetch = (url: string, init?: RequestInit) => Promise<Response>;
const fetchInjectable = getInjectable({
id: "fetch",
instantiate: (di): Fetch => {
const { default: fetch } = di.inject(nodeFetchModuleInjectable);
return (url, init) => fetch(url, init);
},
instantiate: () => fetch as Fetch,
causesSideEffects: true,
});

View File

@ -4,10 +4,10 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import { Agent } from "https";
import type { RequestInit, Response } from "node-fetch";
import type { RequestInit, Response } from "@k8slens/node-fetch";
import lensProxyPortInjectable from "../../main/lens-proxy/lens-proxy-port.injectable";
import lensProxyCertificateInjectable from "../certificate/lens-proxy-certificate.injectable";
import nodeFetchModuleInjectable from "./fetch-module.injectable";
import fetch from "@k8slens/node-fetch";
export type LensRequestInit = Omit<RequestInit, "agent">;
@ -16,7 +16,6 @@ export type LensFetch = (pathnameAndQuery: string, init?: LensRequestInit) => Pr
const lensFetchInjectable = getInjectable({
id: "lens-fetch",
instantiate: (di): LensFetch => {
const { default: fetch } = di.inject(nodeFetchModuleInjectable);
const lensProxyPort = di.inject(lensProxyPortInjectable);
const lensProxyCertificate = di.inject(lensProxyCertificateInjectable);

View File

@ -4,7 +4,7 @@
*/
import type { ApiManager } from "../api-manager";
import type { IngressApi } from "../endpoints";
import { Ingress } from "../endpoints";
import { Ingress, HorizontalPodAutoscalerApi } from "../endpoints";
import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
import type { Fetch } from "../../fetch/fetch.injectable";
import fetchInjectable from "../../fetch/fetch.injectable";
@ -21,6 +21,8 @@ import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kub
import apiManagerInjectable from "../api-manager/manager.injectable";
import type { DiContainer } from "@ogre-tools/injectable";
import ingressApiInjectable from "../endpoints/ingress.api.injectable";
import loggerInjectable from "../../logger.injectable";
import maybeKubeApiInjectable from "../maybe-kube-api.injectable";
describe("KubeApi", () => {
let fetchMock: AsyncFnMock<Fetch>;
@ -705,4 +707,125 @@ describe("KubeApi", () => {
});
});
});
describe("on first call to HorizontalPodAutoscalerApi.get()", () => {
let horizontalPodAutoscalerApi: HorizontalPodAutoscalerApi;
beforeEach(async () => {
horizontalPodAutoscalerApi = new HorizontalPodAutoscalerApi({
logger: di.inject(loggerInjectable),
maybeKubeApi: di.inject(maybeKubeApiInjectable),
}, {
allowedUsableVersions: {
autoscaling: [
"v2",
"v2beta2",
"v2beta1",
"v1",
],
},
});
horizontalPodAutoscalerApi.get({
name: "foo",
namespace: "default",
});
// This is needed because of how JS promises work
await flushPromises();
});
it("requests version list from the api group from the initial apiBase", () => {
expect(fetchMock.mock.lastCall).toMatchObject([
"https://127.0.0.1:12345/api-kube/apis/autoscaling",
{
headers: {
"content-type": "application/json",
},
method: "get",
},
]);
});
describe("when the version list from the api group resolves with preferredVersion in allowed version", () => {
beforeEach(async () => {
await fetchMock.resolveSpecific(
["https://127.0.0.1:12345/api-kube/apis/autoscaling"],
createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/autoscaling", JSON.stringify({
apiVersion: "v1",
kind: "APIGroup",
name: "autoscaling",
versions: [
{
groupVersion: "autoscaling/v1",
version: "v1",
},
{
groupVersion: "autoscaling/v1beta1",
version: "v2beta1",
},
],
preferredVersion: {
groupVersion: "autoscaling/v1",
version: "v1",
},
})),
);
});
it("requests resources from the preferred version api group from the initial apiBase", () => {
expect(fetchMock.mock.lastCall).toMatchObject([
"https://127.0.0.1:12345/api-kube/apis/autoscaling/v1",
{
headers: {
"content-type": "application/json",
},
method: "get",
},
]);
});
});
describe("when the version list from the api group resolves with preferredVersion not allowed version", () => {
beforeEach(async () => {
await fetchMock.resolveSpecific(
["https://127.0.0.1:12345/api-kube/apis/autoscaling"],
createMockResponseFromString("https://127.0.0.1:12345/api-kube/apis/autoscaling", JSON.stringify({
apiVersion: "v1",
kind: "APIGroup",
name: "autoscaling",
versions: [
{
groupVersion: "autoscaling/v2",
version: "v2",
},
{
groupVersion: "autoscaling/v2beta1",
version: "v2beta1",
},
{
groupVersion: "autoscaling/v3",
version: "v3",
},
],
preferredVersion: {
groupVersion: "autoscaling/v3",
version: "v3",
},
})),
);
});
it("requests resources from the non preferred version from the initial apiBase", () => {
expect(fetchMock.mock.lastCall).toMatchObject([
"https://127.0.0.1:12345/api-kube/apis/autoscaling/v2",
{
headers: {
"content-type": "application/json",
},
method: "get",
},
]);
});
});
});
});

View File

@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import { Agent } from "https";
import type { RequestInit } from "node-fetch";
import type { RequestInit } from "@k8slens/node-fetch";
import lensProxyCertificateInjectable from "../certificate/lens-proxy-certificate.injectable";
import fetchInjectable from "../fetch/fetch.injectable";
import loggerInjectable from "../logger.injectable";

View File

@ -5,7 +5,7 @@
import { getInjectable } from "@ogre-tools/injectable";
import type { AgentOptions } from "https";
import { Agent } from "https";
import type { RequestInit } from "node-fetch";
import type { RequestInit } from "@k8slens/node-fetch";
import loggerInjectable from "../logger.injectable";
import isDevelopmentInjectable from "../vars/is-development.injectable";
import createKubeJsonApiInjectable from "./create-kube-json-api.injectable";

View File

@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import { Agent } from "https";
import type { RequestInit } from "node-fetch";
import type { RequestInit } from "@k8slens/node-fetch";
import lensProxyCertificateInjectable from "../certificate/lens-proxy-certificate.injectable";
import fetchInjectable from "../fetch/fetch.injectable";
import loggerInjectable from "../logger.injectable";

View File

@ -371,6 +371,14 @@ export class HorizontalPodAutoscaler extends KubeObject<
export class HorizontalPodAutoscalerApi extends KubeApi<HorizontalPodAutoscaler> {
constructor(deps: KubeApiDependencies, opts?: DerivedKubeApiOptions) {
super(deps, {
allowedUsableVersions: {
autoscaling: [
"v2",
"v2beta2",
"v2beta1",
"v1",
],
},
...opts ?? {},
objectConstructor: HorizontalPodAutoscaler,
checkPreferredVersion: true,

View File

@ -18,6 +18,14 @@ const podDisruptionBudgetApiInjectable = getInjectable({
return new PodDisruptionBudgetApi({
logger: di.inject(loggerInjectable),
maybeKubeApi: di.inject(maybeKubeApiInjectable),
}, {
checkPreferredVersion: true,
allowedUsableVersions: {
policy: [
"v1",
"v1beta1",
],
},
});
},

View File

@ -7,20 +7,45 @@ import type { LabelSelector, NamespaceScopedMetadata } from "../kube-object";
import { KubeObject } from "../kube-object";
import type { DerivedKubeApiOptions, KubeApiDependencies } from "../kube-api";
import { KubeApi } from "../kube-api";
import type { Condition } from "./types/condition";
export interface PodDisruptionBudgetSpec {
export interface V1Beta1PodDisruptionBudgetSpec {
minAvailable: string;
maxUnavailable: string;
selector: LabelSelector;
}
export interface PodDisruptionBudgetStatus {
export interface V1PodDisruptionBudgetSpec {
maxUnavailable?: string | number;
minAvailable?: string | number;
selector?: LabelSelector;
}
export type PodDisruptionBudgetSpec =
| V1Beta1PodDisruptionBudgetSpec
| V1PodDisruptionBudgetSpec;
export interface V1Beta1PodDisruptionBudgetStatus {
currentHealthy: number;
desiredHealthy: number;
disruptionsAllowed: number;
expectedPods: number;
}
export interface V1PodDisruptionBudgetStatus {
conditions?: Condition[];
currentHealthy: number;
desiredHealthy: number;
disruptedPods?: Partial<Record<string, string>>;
disruptionsAllowed: number;
expectedPods: number;
observedGeneration?: number;
}
export type PodDisruptionBudgetStatus =
| V1Beta1PodDisruptionBudgetStatus
| V1PodDisruptionBudgetStatus;
export class PodDisruptionBudget extends KubeObject<
NamespaceScopedMetadata,
PodDisruptionBudgetStatus,
@ -31,7 +56,7 @@ export class PodDisruptionBudget extends KubeObject<
static readonly apiBase = "/apis/policy/v1beta1/poddisruptionbudgets";
getSelectors() {
return KubeObject.stringifyLabels(this.spec.selector.matchLabels);
return KubeObject.stringifyLabels(this.spec.selector?.matchLabels);
}
getMinAvailable() {

View File

@ -0,0 +1,13 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export interface Condition {
lastTransitionTime: string;
message: string;
observedGeneration?: number;
reason: string;
status: string;
type: string;
}

View File

@ -8,7 +8,7 @@
import { Agent as HttpAgent } from "http";
import { Agent as HttpsAgent } from "https";
import { merge } from "lodash";
import type { Response, RequestInit } from "node-fetch";
import type { Response, RequestInit } from "@k8slens/node-fetch";
import { stringify } from "querystring";
import type { Patch } from "rfc6902";
import type { PartialDeep, ValueOf } from "type-fest";

View File

@ -15,7 +15,7 @@ import type { IKubeWatchEvent } from "./kube-watch-event";
import type { KubeJsonApiData, KubeJsonApi } from "./kube-json-api";
import type { Disposer } from "../utils";
import { isDefined, noop, WrappedAbortController } from "../utils";
import type { RequestInit, Response } from "node-fetch";
import type { RequestInit, Response } from "@k8slens/node-fetch";
import type { Patch } from "rfc6902";
import assert from "assert";
import type { PartialDeep } from "type-fest";
@ -58,14 +58,32 @@ export interface DerivedKubeApiOptions {
/**
* If the API uses a different API endpoint (e.g. apiBase) depending on the cluster version,
* fallback API bases can be listed individually.
*
* The first (existing) API base is used in the requests, if apiBase is not found.
* This option only has effect if checkPreferredVersion is true.
*
* This option only has effect if {@link DerivedKubeApiOptions.checkPreferredVersion} is `true`.
*/
fallbackApiBases?: string[];
/**
* This option is useful for protecting against newer versions on the same apiBase from being
* used. So that if a certain type only supports `v1`, or `v2` of some kind and then the `v3`
* version becomes the `preferredVersion` on the server but still has `v2` then the `v2` version
* will be used instead.
*
* This can help to prevent crashes in the future if the shape of a kind sufficently changes.
*
* The order is important. It should be sorted and the first entry should be the most preferable.
*
* This option only has effect if {@link DerivedKubeApiOptions.checkPreferredVersion} is `true`
*/
allowedUsableVersions?: Partial<Record<string, [string, ...string[]]>>;
/**
* If `true` then will check all declared apiBases against the kube api server
* for the first accepted one.
*
* @default false
*/
checkPreferredVersion?: boolean;
@ -133,10 +151,10 @@ export interface KubeApiResourceVersionList {
const not = <T>(fn: (val: T) => boolean) => (val: T) => !(fn(val));
const getOrderedVersions = (list: KubeApiResourceVersionList): KubeApiResourceVersion[] => [
const getOrderedVersions = (list: KubeApiResourceVersionList, allowedUsableVersions: string[] | undefined): KubeApiResourceVersion[] => [
list.preferredVersion,
...list.versions.filter(not(matches(list.preferredVersion))),
];
].filter(({ version }) => !allowedUsableVersions || allowedUsableVersions.includes(version));
export type PropagationPolicy = undefined | "Orphan" | "Foreground" | "Background";
@ -233,6 +251,7 @@ export class KubeApi<
protected readonly doCheckPreferredVersion: boolean;
protected readonly fullApiPathname: string;
protected readonly fallbackApiBases: string[] | undefined;
protected readonly allowedUsableVersions: Partial<Record<string, string[]>> | undefined;
constructor(protected readonly dependencies: KubeApiDependencies, opts: KubeApiOptions<Object, Data>) {
const {
@ -243,6 +262,7 @@ export class KubeApi<
apiBase: fullApiPathname = objectConstructor.apiBase,
checkPreferredVersion: doCheckPreferredVersion = false,
fallbackApiBases,
allowedUsableVersions,
} = opts;
assert(fullApiPathname, "apiBase MUST be provied either via KubeApiOptions.apiBase or KubeApiOptions.objectConstructor.apiBase");
@ -255,6 +275,7 @@ export class KubeApi<
this.doCheckPreferredVersion = doCheckPreferredVersion;
this.fallbackApiBases = fallbackApiBases;
this.allowedUsableVersions = allowedUsableVersions;
this.fullApiPathname = fullApiPathname;
this.kind = kind;
this.isNamespaced = isNamespaced ?? objectConstructor.namespaced ?? false;
@ -291,7 +312,7 @@ export class KubeApi<
try {
const { apiPrefix, apiGroup, resource } = parseKubeApi(apiUrl);
const list = await this.request.get(`${apiPrefix}/${apiGroup}`) as KubeApiResourceVersionList;
const resourceVersions = getOrderedVersions(list);
const resourceVersions = getOrderedVersions(list, this.allowedUsableVersions?.[apiGroup]);
for (const resourceVersion of resourceVersions) {
const { resources } = await this.request.get(`${apiPrefix}/${resourceVersion.groupVersion}`) as KubeApiResourceList;
@ -313,8 +334,8 @@ export class KubeApi<
}
protected async checkPreferredVersion() {
if (this.fallbackApiBases && !this.doCheckPreferredVersion) {
throw new Error("checkPreferredVersion must be enabled if fallbackApiBases is set in KubeApi");
if (!this.doCheckPreferredVersion && (this.fallbackApiBases || this.allowedUsableVersions)) {
throw new Error("checkPreferredVersion must be enabled if either fallbackApiBases or allowedUsableVersions are set in KubeApi");
}
if (this.doCheckPreferredVersion && this.apiVersionPreferred === undefined) {

View File

@ -5,7 +5,7 @@
import type { JsonApiData, JsonApiError } from "./json-api";
import { JsonApi } from "./json-api";
import type { Response } from "node-fetch";
import type { Response } from "@k8slens/node-fetch";
import type { KubeJsonApiObjectMetadata } from "./kube-object";
export interface KubeJsonApiListMetadata {

View File

@ -12,7 +12,7 @@ import type { IKubeWatchEvent } from "./kube-watch-event";
import { ItemStore } from "../item.store";
import type { KubeApiQueryParams, KubeApi, KubeApiWatchCallback } from "./kube-api";
import { parseKubeApi } from "./kube-api-parse";
import type { RequestInit } from "node-fetch";
import type { RequestInit } from "@k8slens/node-fetch";
import type { Patch } from "rfc6902";
import type { Logger } from "../logger";
import assert from "assert";

View File

@ -0,0 +1,70 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { AsyncResult } from "./async-result";
import { delay } from "./delay";
import { noop } from "./noop";
/**
* @param error The error that resulted in the failure
* @param attempt The 1-index attempt count
*/
export type OnIntermediateError<E> = (error: E, attempt: number) => void;
export interface BackoffCallerOptions<E> {
/**
* Called when an attempt fails
*/
onIntermediateError?: OnIntermediateError<E>;
/**
* @default 5
*/
maxAttempts?: number;
/**
* In miliseconds
* @default 1000
*/
initialTimeout?: number;
/**
* @default 2
*/
scaleFactor?: number;
}
/**
* Calls `fn` once and then again (with exponential delay between each attempt) up to `options.maxAttempts` times.
* @param fn The function to repeatedly attempt
* @returns The first success or the last failure
*/
export const backoffCaller = async <T, E, R extends AsyncResult<T, E>>(fn: () => Promise<R>, options?: BackoffCallerOptions<E>): Promise<R> => {
const {
initialTimeout = 1000,
maxAttempts = 5,
onIntermediateError = noop as OnIntermediateError<E>,
scaleFactor = 2,
} = options ?? {};
let timeout = initialTimeout;
let attempt = 0;
let result: R;
do {
result = await fn();
if (result.callWasSuccessful) {
return result;
}
onIntermediateError(result.error, attempt + 1);
await delay(timeout);
timeout *= scaleFactor;
} while (attempt += 1, attempt < maxAttempts);
return result;
};

View File

@ -11,26 +11,17 @@ import isWindowsInjectable from "../../common/vars/is-windows.injectable";
import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import getEnabledExtensionsInjectable from "./get-enabled-extensions/get-enabled-extensions.injectable";
import type { UserPreferenceExtensionItems } from "./user-preferences";
import { Preferences } from "./user-preferences";
import { slackUrl, issuesTrackerUrl } from "../../common/vars";
import { buildVersionInjectionToken } from "../../common/vars/build-semantic-version.injectable";
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import userStoreInjectable from "../../common/user-store/user-store.injectable";
export interface AppExtensionItems {
readonly Preferences: UserPreferenceExtensionItems;
readonly version: string;
readonly appName: string;
readonly slackUrl: string;
readonly issuesTrackerUrl: string;
readonly isSnap: boolean;
readonly isWindows: boolean;
readonly isMac: boolean;
readonly isLinux: boolean;
getEnabledExtensions: () => string[];
}
const userStore = asLegacyGlobalForExtensionApi(userStoreInjectable);
export const App: AppExtensionItems = {
Preferences,
export const App = {
Preferences: {
getKubectlPath: () => userStore.kubectlBinariesPath,
},
getEnabledExtensions: asLegacyGlobalFunctionForExtensionApi(getEnabledExtensionsInjectable),
get version() {
const di = getLegacyGlobalDiForExtensionApi();
@ -64,4 +55,4 @@ export const App: AppExtensionItems = {
},
slackUrl,
issuesTrackerUrl,
};
} as const;

View File

@ -3,6 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { KubernetesClusterCategory } from "../../common/catalog-entities/kubernetes-cluster";
import kubernetesClusterCategoryInjectable from "../../common/catalog/categories/kubernetes-cluster.injectable";
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
@ -12,6 +13,10 @@ export {
WebLink,
} from "../../common/catalog-entities";
export type {
KubernetesClusterCategory,
};
export const kubernetesClusterCategory = asLegacyGlobalForExtensionApi(kubernetesClusterCategoryInjectable);
export type {
@ -23,6 +28,7 @@ export type {
WebLinkStatusPhase,
KubernetesClusterStatusPhase,
KubernetesClusterStatus,
GeneralEntitySpec,
} from "../../common/catalog-entities";
export * from "../../common/catalog/catalog-entity";

View File

@ -5,7 +5,14 @@
import appEventBusInjectable from "../../common/app-event-bus/app-event-bus.injectable";
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import type { AppEvent } from "../../common/app-event-bus/event-bus";
import type { EventEmitter, EventEmitterCallback, EventEmitterOptions } from "../../common/event-emitter";
export type { AppEvent } from "../../common/app-event-bus/event-bus";
export type {
AppEvent,
EventEmitter,
EventEmitterCallback,
EventEmitterOptions,
};
export const appEventBus = asLegacyGlobalForExtensionApi(appEventBusInjectable);

View File

@ -13,6 +13,8 @@ import * as Types from "./types";
import * as Proxy from "./proxy";
import loggerInjectable from "../../common/logger.injectable";
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import type { Logger } from "../../common/logger";
import type { LensExtension, LensExtensionManifest } from "../lens-extension";
const logger = asLegacyGlobalForExtensionApi(loggerInjectable);
@ -25,4 +27,7 @@ export {
Util,
logger,
Proxy,
Logger,
LensExtension,
LensExtensionManifest,
};

View File

@ -30,7 +30,7 @@ import { storesAndApisCanBeCreatedInjectionToken } from "../../common/k8s-api/st
import type { JsonApiConfig } from "../../common/k8s-api/json-api";
import type { KubeJsonApi as InternalKubeJsonApi } from "../../common/k8s-api/kube-json-api";
import createKubeJsonApiInjectable from "../../common/k8s-api/create-kube-json-api.injectable";
import type { RequestInit } from "node-fetch";
import type { RequestInit } from "@k8slens/node-fetch";
import createKubeJsonApiForClusterInjectable from "../../common/k8s-api/create-kube-json-api-for-cluster.injectable";
export const apiManager = asLegacyGlobalForExtensionApi(apiManagerInjectable);

View File

@ -3,4 +3,10 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
export { ExtensionStore } from "../extension-store";
import type { BaseStoreParams } from "../../common/base-store/base-store";
import { ExtensionStore } from "../extension-store";
export {
BaseStoreParams,
ExtensionStore,
};

View File

@ -1,19 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import userStoreInjectable from "../../common/user-store/user-store.injectable";
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
export interface UserPreferenceExtensionItems {
/**
* Get the configured kubectl binaries path.
*/
getKubectlPath: () => string | undefined;
}
const userStore = asLegacyGlobalForExtensionApi(userStoreInjectable);
export const Preferences: UserPreferenceExtensionItems = {
getKubectlPath: () => userStore.kubectlBinariesPath,
};

View File

@ -9,20 +9,9 @@ import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-
import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import { Singleton } from "../../common/utils";
import { prevDefault, stopPropagation } from "../../renderer/utils/prevDefault";
import type { IClassName } from "../../renderer/utils/cssNames";
import { cssNames } from "../../renderer/utils/cssNames";
export interface UtilsExtensionItems {
Singleton: typeof Singleton;
prevDefault: <E extends React.SyntheticEvent | Event, R>(callback: (evt: E) => R) => (evt: E) => R;
stopPropagation: (evt: Event | React.SyntheticEvent) => void;
cssNames: (...classNames: IClassName[]) => string;
openExternal: (url: string) => Promise<void>;
openBrowser: (url: string) => Promise<void>;
getAppVersion: () => string;
}
export const Util: UtilsExtensionItems = {
export const Util = {
Singleton,
prevDefault,
stopPropagation,
@ -34,4 +23,4 @@ export const Util: UtilsExtensionItems = {
return di.inject(buildVersionInjectable).get();
},
};
} as const;

View File

@ -32,7 +32,12 @@ export interface LensExtensionManifest extends PackageJson {
export const lensExtensionDependencies = Symbol("lens-extension-dependencies");
export const Disposers = Symbol("disposers");
export class LensExtension<Dependencies extends LensExtensionDependencies = LensExtensionDependencies> {
export class LensExtension<
/**
* @ignore
*/
Dependencies extends LensExtensionDependencies = LensExtensionDependencies,
> {
readonly id: LensExtensionId;
readonly manifest: LensExtensionManifest;
readonly manifestPath: string;
@ -50,6 +55,9 @@ export class LensExtension<Dependencies extends LensExtensionDependencies = Lens
return this._isEnabled;
}
/**
* @ignore
*/
[Disposers] = disposer();
constructor({ id, manifest, manifestPath, isBundled }: InstalledExtension) {
@ -72,6 +80,9 @@ export class LensExtension<Dependencies extends LensExtensionDependencies = Lens
return this.manifest.description;
}
/**
* @ignore
*/
readonly [lensExtensionDependencies]!: Dependencies;
/**

View File

@ -200,34 +200,34 @@ describe("kube auth proxy tests", () => {
await proxy.run();
listeners.emit("error", { message: "foobarbat" });
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "foobarbat", isError: true });
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "foobarbat", level: "error" });
});
it("should call spawn and broadcast exit", async () => {
await proxy.run();
listeners.emit("exit", 0);
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "proxy exited with code: 0", isError: false });
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "proxy exited with code: 0", level: "info" });
});
it("should call spawn and broadcast errors from stderr", async () => {
await proxy.run();
listeners.emit("stderr/data", "an error");
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "an error", isError: true });
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "an error", level: "error" });
});
it("should call spawn and broadcast stdout serving info", async () => {
await proxy.run();
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "Authentication proxy started", isError: false });
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "Authentication proxy started", level: "info" });
});
it("should call spawn and broadcast stdout other info", async () => {
await proxy.run();
listeners.emit("stdout/data", "some info");
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "some info", isError: false });
expect(broadcastMessageMock).toBeCalledWith("cluster:foobar:connection-update", { message: "some info", level: "info" });
});
});
});

View File

@ -10,8 +10,10 @@ import type { Cluster } from "../../common/cluster/cluster";
import { requestApiVersionsInjectionToken } from "./request-api-versions";
import { withConcurrencyLimit } from "../../common/utils/with-concurrency-limit";
import requestKubeApiResourcesForInjectable from "./request-kube-api-resources-for.injectable";
import type { AsyncResult } from "../../common/utils/async-result";
import { backoffCaller } from "../../common/utils/backoff-caller";
export type RequestApiResources = (cluster: Cluster) => Promise<KubeApiResource[]>;
export type RequestApiResources = (cluster: Cluster) => Promise<AsyncResult<KubeApiResource[], Error>>;
export interface KubeResourceListGroup {
group: string;
@ -25,23 +27,46 @@ const requestApiResourcesInjectable = getInjectable({
const apiVersionRequesters = di.injectMany(requestApiVersionsInjectionToken);
const requestKubeApiResourcesFor = di.inject(requestKubeApiResourcesForInjectable);
return async (cluster) => {
return async (...args) => {
const [cluster] = args;
const requestKubeApiResources = withConcurrencyLimit(5)(requestKubeApiResourcesFor(cluster));
try {
const requests = await Promise.all(apiVersionRequesters.map(fn => fn(cluster)));
const resources = await Promise.all((
requests
.flat()
.map(requestKubeApiResources)
));
const groupLists: KubeResourceListGroup[] = [];
return resources.flat();
} catch (error) {
logger.error(`[LIST-API-RESOURCES]: failed to list api resources: ${error}`);
for (const apiVersionRequester of apiVersionRequesters) {
const result = await backoffCaller(() => apiVersionRequester(cluster), {
onIntermediateError: (error, attempt) => {
cluster.broadcastConnectUpdate(`Failed to list kube API resource kinds, attempt ${attempt}: ${error}`, "warning");
logger.warn(`[LIST-API-RESOURCES]: failed to list kube api resources: ${error}`, { attempt, clusterId: cluster.id });
},
});
return [];
if (!result.callWasSuccessful) {
return result;
}
groupLists.push(...result.response);
}
const apiResourceRequests = groupLists.map(async listGroup => (
Object.assign(await requestKubeApiResources(listGroup), { listGroup })
));
const results = await Promise.all(apiResourceRequests);
const resources: KubeApiResource[] = [];
for (const result of results) {
if (!result.callWasSuccessful) {
cluster.broadcastConnectUpdate(`Kube APIs under "${result.listGroup.path}" may not be displayed`, "warning");
continue;
}
resources.push(...result.response);
}
return {
callWasSuccessful: true,
response: resources,
};
};
},
});

View File

@ -5,13 +5,14 @@
import { getInjectionToken } from "@ogre-tools/injectable";
import type { Cluster } from "../../common/cluster/cluster";
import type { AsyncResult } from "../../common/utils/async-result";
export interface KubeResourceListGroup {
group: string;
path: string;
}
export type RequestApiVersions = (cluster: Cluster) => Promise<KubeResourceListGroup[]>;
export type RequestApiVersions = (cluster: Cluster) => Promise<AsyncResult<KubeResourceListGroup[], Error>>;
export const requestApiVersionsInjectionToken = getInjectionToken<RequestApiVersions>({
id: "request-api-versions-token",

View File

@ -13,12 +13,22 @@ const requestCoreApiVersionsInjectable = getInjectable({
const k8sRequest = di.inject(k8sRequestInjectable);
return async (cluster) => {
const { versions } = await k8sRequest(cluster, "/api") as V1APIVersions;
try {
const { versions } = await k8sRequest(cluster, "/api") as V1APIVersions;
return versions.map(version => ({
group: "",
path: `/api/${version}`,
}));
return {
callWasSuccessful: true,
response: versions.map(version => ({
group: "",
path: `/api/${version}`,
})),
};
} catch (error) {
return {
callWasSuccessful: false,
error: error as Error,
};
}
};
},
injectionToken: requestApiVersionsInjectionToken,

View File

@ -6,10 +6,11 @@ import type { V1APIResourceList } from "@kubernetes/client-node";
import { getInjectable } from "@ogre-tools/injectable";
import type { Cluster } from "../../common/cluster/cluster";
import type { KubeApiResource } from "../../common/rbac";
import type { AsyncResult } from "../../common/utils/async-result";
import k8sRequestInjectable from "../k8s-request.injectable";
import type { KubeResourceListGroup } from "./request-api-versions";
export type RequestKubeApiResources = (grouping: KubeResourceListGroup) => Promise<KubeApiResource[]>;
export type RequestKubeApiResources = (grouping: KubeResourceListGroup) => Promise<AsyncResult<KubeApiResource[], Error>>;
export type RequestKubeApiResourcesFor = (cluster: Cluster) => RequestKubeApiResources;
@ -19,14 +20,24 @@ const requestKubeApiResourcesForInjectable = getInjectable({
const k8sRequest = di.inject(k8sRequestInjectable);
return (cluster) => async ({ group, path }) => {
const { resources } = await k8sRequest(cluster, path) as V1APIResourceList;
try {
const { resources } = await k8sRequest(cluster, path) as V1APIResourceList;
return resources.map(resource => ({
apiName: resource.name,
kind: resource.kind,
group,
namespaced: resource.namespaced,
}));
return {
callWasSuccessful: true,
response: resources.map(resource => ({
apiName: resource.name,
kind: resource.kind,
group,
namespaced: resource.namespaced,
})),
};
} catch (error) {
return {
callWasSuccessful: false,
error: error as Error,
};
}
};
},
});

View File

@ -14,14 +14,24 @@ const requestNonCoreApiVersionsInjectable = getInjectable({
const k8sRequest = di.inject(k8sRequestInjectable);
return async (cluster) => {
const { groups } = await k8sRequest(cluster, "/apis") as V1APIGroupList;
try {
const { groups } = await k8sRequest(cluster, "/apis") as V1APIGroupList;
return chain(groups.values())
.filterMap(group => group.preferredVersion?.groupVersion && ({
group: group.name,
path: `/apis/${group.preferredVersion.groupVersion}`,
}))
.collect(v => [...v]);
return {
callWasSuccessful: true,
response: chain(groups.values())
.filterMap(group => group.preferredVersion?.groupVersion && ({
group: group.name,
path: `/apis/${group.preferredVersion.groupVersion}`,
}))
.collect(v => [...v]),
};
} catch (error) {
return {
callWasSuccessful: false,
error: error as Error,
};
}
};
},
injectionToken: requestApiVersionsInjectionToken,

View File

@ -19,6 +19,10 @@ const LensExtensions = {
Main: LensExtensionsMainApi,
};
export type {
LensExtensionsMainApi,
};
const Pty = {
spawn,
};

View File

@ -4,7 +4,7 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import type { Cluster } from "../common/cluster/cluster";
import nodeFetchModuleInjectable from "../common/fetch/fetch-module.injectable";
import { FormData } from "@k8slens/node-fetch";
import type { RequestMetricsParams } from "../common/k8s-api/endpoints/metrics.api/request-metrics.injectable";
import { object } from "../common/utils";
import k8sRequestInjectable from "./k8s-request.injectable";
@ -16,7 +16,6 @@ const getMetricsInjectable = getInjectable({
instantiate: (di): GetMetrics => {
const k8sRequest = di.inject(k8sRequestInjectable);
const { FormData } = di.inject(nodeFetchModuleInjectable);
return async (
cluster,

View File

@ -71,17 +71,17 @@ export class KubeAuthProxy {
},
});
this.proxyProcess.on("error", (error) => {
this.cluster.broadcastConnectUpdate(error.message, true);
this.cluster.broadcastConnectUpdate(error.message, "error");
this.exit();
});
this.proxyProcess.on("exit", (code) => {
this.cluster.broadcastConnectUpdate(`proxy exited with code: ${code}`, code ? code > 0: false);
this.cluster.broadcastConnectUpdate(`proxy exited with code: ${code}`, code ? "error" : "info");
this.exit();
});
this.proxyProcess.on("disconnect", () => {
this.cluster.broadcastConnectUpdate("Proxy disconnected communications", true );
this.cluster.broadcastConnectUpdate("Proxy disconnected communications", "error");
this.exit();
});
@ -93,7 +93,7 @@ export class KubeAuthProxy {
return;
}
this.cluster.broadcastConnectUpdate(data.toString(), true);
this.cluster.broadcastConnectUpdate(data.toString(), "error");
});
this.proxyProcess.stdout.on("data", (data: Buffer) => {
@ -114,7 +114,7 @@ export class KubeAuthProxy {
this.ready = true;
} catch (error) {
this.dependencies.logger.warn("[KUBE-AUTH-PROXY]: waitUntilUsed failed", error);
this.cluster.broadcastConnectUpdate("Proxy port failed to be used within timelimit, restarting...", true);
this.cluster.broadcastConnectUpdate("Proxy port failed to be used within timelimit, restarting...", "error");
this.exit();
return this.run();

View File

@ -11,7 +11,7 @@ import * as extensionApi from "./extension-api";
import { createApp } from "./create-app";
// @experimental
export {
export {
createApp,
extensionApi,
afterApplicationIsLoadedInjectionToken,

View File

@ -0,0 +1,326 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<HpaDetails/> renders 1`] = `
<body>
<div>
<div
class="HpaDetails"
>
<div
class="DrawerItem"
>
<span
class="name"
>
Reference
</span>
<span
class="value"
>
Deployment
/
hpav2deployment
</span>
</div>
<div
class="DrawerItem"
>
<span
class="name"
>
Min Pods
</span>
<span
class="value"
>
0
</span>
</div>
<div
class="DrawerItem"
>
<span
class="name"
>
Max Pods
</span>
<span
class="value"
>
10
</span>
</div>
<div
class="DrawerItem"
>
<span
class="name"
>
Replicas
</span>
<span
class="value"
>
0
</span>
</div>
<div
class="DrawerItem status labelsOnly"
>
<span
class="name"
>
Status
</span>
<span
class="value"
/>
</div>
</div>
</div>
</body>
`;
exports[`<HpaDetails/> shows unknown metrics with lack of metric type 1`] = `
<body>
<div>
<div
class="HpaDetails"
>
<div
class="DrawerItem"
>
<span
class="name"
>
Reference
</span>
<span
class="value"
>
Deployment
/
hpav2deployment
</span>
</div>
<div
class="DrawerItem"
>
<span
class="name"
>
Min Pods
</span>
<span
class="value"
>
0
</span>
</div>
<div
class="DrawerItem"
>
<span
class="name"
>
Max Pods
</span>
<span
class="value"
>
10
</span>
</div>
<div
class="DrawerItem"
>
<span
class="name"
>
Replicas
</span>
<span
class="value"
>
0
</span>
</div>
<div
class="DrawerItem status labelsOnly"
>
<span
class="name"
>
Status
</span>
<span
class="value"
/>
</div>
<div
class="DrawerTitle title"
>
Metrics
</div>
<div
class="metrics"
>
<div
class="Table flex column scrollable autoSize"
>
<div
class="TableHead sticky flat"
>
<div
class="TableCell name"
>
Name
</div>
<div
class="TableCell metrics"
>
Current / Target
</div>
</div>
<div
class="TableRow"
>
<div
class="TableCell name"
>
unknown
</div>
<div
class="TableCell metrics"
>
unknown / unknown
</div>
</div>
</div>
</div>
</div>
</div>
</body>
`;
exports[`<HpaDetails/> shows unknown metrics with with unusual type 1`] = `
<body>
<div>
<div
class="HpaDetails"
>
<div
class="DrawerItem"
>
<span
class="name"
>
Reference
</span>
<span
class="value"
>
Deployment
/
hpav2deployment
</span>
</div>
<div
class="DrawerItem"
>
<span
class="name"
>
Min Pods
</span>
<span
class="value"
>
0
</span>
</div>
<div
class="DrawerItem"
>
<span
class="name"
>
Max Pods
</span>
<span
class="value"
>
10
</span>
</div>
<div
class="DrawerItem"
>
<span
class="name"
>
Replicas
</span>
<span
class="value"
>
0
</span>
</div>
<div
class="DrawerItem status labelsOnly"
>
<span
class="name"
>
Status
</span>
<span
class="value"
/>
</div>
<div
class="DrawerTitle title"
>
Metrics
</div>
<div
class="metrics"
>
<div
class="Table flex column scrollable autoSize"
>
<div
class="TableHead sticky flat"
>
<div
class="TableCell name"
>
Name
</div>
<div
class="TableCell metrics"
>
Current / Target
</div>
</div>
<div
class="TableRow"
>
<div
class="TableCell name"
>
unknown
</div>
<div
class="TableCell metrics"
>
unknown / unknown
</div>
</div>
</div>
</div>
</div>
</div>
</body>
`;

View File

@ -19,8 +19,8 @@ interface Metric extends MetricNames {
type: HpaMetricType;
}
export function getMetricName(metric: Metric): string | undefined {
switch (metric.type) {
export function getMetricName(metric: Metric | undefined): string | undefined {
switch (metric?.type) {
case HpaMetricType.Resource:
return metric.resource?.name;
case HpaMetricType.Pods:

View File

@ -0,0 +1,392 @@
/**
* 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 React from "react";
import { HorizontalPodAutoscaler, HpaMetricType } from "../../../common/k8s-api/endpoints";
import { getDiForUnitTesting } from "../../getDiForUnitTesting";
import type { DiRender } from "../test-utils/renderFor";
import { renderFor } from "../test-utils/renderFor";
import { HpaDetails } from "./hpa-details";
jest.mock("react-router-dom", () => ({
Link: ({ children }: { children: React.ReactNode }) => children,
}));
const hpaV2 = {
apiVersion: "autoscaling/v2",
kind: "HorizontalPodAutoscaler",
metadata: {
name: "hpav2",
resourceVersion: "1",
uid: "hpav2",
namespace: "default",
selfLink: "/apis/autoscaling/v2/namespaces/default/horizontalpodautoscalers/hpav2",
},
spec: {
maxReplicas: 10,
scaleTargetRef: {
kind: "Deployment",
name: "hpav2deployment",
apiVersion: "apps/v1",
},
},
};
describe("<HpaDetails/>", () => {
let result: RenderResult;
let render: DiRender;
beforeEach(() => {
const di = getDiForUnitTesting({ doGeneralOverrides: true });
render = renderFor(di);
});
it("renders", () => {
const hpa = new HorizontalPodAutoscaler(hpaV2);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.baseElement).toMatchSnapshot();
});
it("does not show metrics table if no metrics found", () => {
const hpa = new HorizontalPodAutoscaler(hpaV2);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.queryByTestId("hpa-metrics")).toBeNull();
});
it("shows proper metric name for autoscaling/v1", () => {
const hpa = new HorizontalPodAutoscaler({
apiVersion: "autoscaling/v1",
kind: "HorizontalPodAutoscaler",
metadata: {
name: "hpav1",
resourceVersion: "1",
uid: "hpav1",
namespace: "default",
selfLink: "/apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/hpav1",
},
spec: {
maxReplicas: 10,
scaleTargetRef: {
kind: "Deployment",
name: "hpav1deployment",
apiVersion: "apps/v1",
},
targetCPUUtilizationPercentage: 80,
},
});
result = render(
<HpaDetails object={hpa} />,
);
expect(result.getByText("CPU Utilization percentage")).toBeInTheDocument();
});
it("shows proper metric name for container resource metrics", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
{
type: HpaMetricType.ContainerResource,
containerResource: {
name: "cpu",
container: "nginx",
target: {
type: "Utilization",
averageUtilization: 60,
},
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.getByText("Resource cpu on Pods")).toBeInTheDocument();
});
it("shows proper metric name for resource metrics", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
{
type: HpaMetricType.Resource,
resource: {
name: "cpu",
target: {
type: "Utilization",
averageUtilization: 50,
},
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.getByText("Resource cpu on Pods")).toBeInTheDocument();
});
it("shows proper metric name for pod metrics for hpa v2", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
{
type: HpaMetricType.Pods,
pods: {
metric: {
name: "packets-per-second",
},
target: {
type: "AverageValue",
averageValue: "1k",
},
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.getByText("packets-per-second on Pods")).toBeInTheDocument();
});
it("shows proper metric name for pod metrics for hpa v2beta1", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
{
type: HpaMetricType.Pods,
pods: {
metricName: "packets-per-second",
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.getByText("packets-per-second on Pods")).toBeInTheDocument();
});
it("shows proper metric name for object metrics for hpa v2", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
{
type: HpaMetricType.Object,
object: {
metric: {
name: "requests-per-second",
},
target: {
type: "Value",
value: "10k",
},
describedObject: {
kind: "Service",
name: "nginx",
apiVersion: "v1",
},
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.getByText(/requests-per-second/)).toHaveTextContent("requests-per-second onService/nginx");
});
it("shows proper metric name for object metrics for hpa v2beta1", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
{
type: HpaMetricType.Object,
object: {
metricName: "requests-per-second",
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.getByText("requests-per-second")).toBeInTheDocument();
});
it("shows proper metric name for external metrics for hpa v2", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
{
type: HpaMetricType.External,
external: {
metric: {
name: "queue_messages_ready",
selector: {
matchLabels: { queue: "worker_tasks" },
},
},
target: {
type: "AverageValue",
averageValue: "30",
},
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.getByText("queue_messages_ready on {\"matchLabels\":{\"queue\":\"worker_tasks\"}}")).toBeInTheDocument();
});
it("shows proper metric name for external metrics for hpa v2beta1", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
{
type: HpaMetricType.External,
external: {
metricName: "queue_messages_ready",
metricSelector: {
matchLabels: { queue: "worker_tasks" },
},
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.getByText("queue_messages_ready on {\"matchLabels\":{\"queue\":\"worker_tasks\"}}")).toBeInTheDocument();
});
it("shows unknown metrics with lack of metric type", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
// @ts-ignore
{
resource: {
name: "cpu",
target: {
type: "Utilization",
averageUtilization: 50,
},
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.baseElement).toMatchSnapshot();
});
it("shows unknown metrics with with unusual type", () => {
const hpa = new HorizontalPodAutoscaler(
{
...hpaV2,
spec: {
...hpaV2.spec,
metrics: [
{
// @ts-ignore
type: "Unusual",
resource: {
name: "cpu",
target: {
type: "Utilization",
averageUtilization: 50,
},
},
},
],
},
},
);
result = render(
<HpaDetails object={hpa} />,
);
expect(result.baseElement).toMatchSnapshot();
});
});

View File

@ -62,7 +62,7 @@ class NonInjectedHpaDetails extends React.Component<HpaDetailsProps & Dependenci
const renderName = (metric: HorizontalPodAutoscalerMetricSpec) => {
const metricName = getMetricName(metric);
switch (metric.type) {
switch (metric?.type) {
case HpaMetricType.ContainerResource:
// fallthrough
@ -85,11 +85,13 @@ class NonInjectedHpaDetails extends React.Component<HpaDetailsProps & Dependenci
}
case HpaMetricType.External:
return `${metricName} on ${JSON.stringify(metric.external.metricSelector ?? metric.external.metric?.selector)}`;
default:
return hpa.spec?.targetCPUUtilizationPercentage ? "CPU Utilization percentage" : "unknown";
}
};
return (
<Table>
<Table data-testid="hpa-metrics">
<TableHead flat>
<TableCell className="name">Name</TableCell>
<TableCell className="metrics">Current / Target</TableCell>
@ -162,10 +164,14 @@ class NonInjectedHpaDetails extends React.Component<HpaDetailsProps & Dependenci
))}
</DrawerItem>
<DrawerTitle>Metrics</DrawerTitle>
<div className="metrics">
{this.renderMetrics()}
</div>
{(hpa.getMetrics().length !== 0 || hpa.spec?.targetCPUUtilizationPercentage) && (
<>
<DrawerTitle>Metrics</DrawerTitle>
<div className="metrics">
{this.renderMetrics()}
</div>
</>
)}
</div>
);
}

View File

@ -113,6 +113,11 @@ class NonInjectedConfigMapDetails extends React.Component<ConfigMapDetailsProps
value={value}
onChange={v => this.data.set(name, v)}
setInitialHeight
options={{
scrollbar: {
alwaysConsumeMouseWheel: false,
},
}}
/>
</div>
))

View File

@ -10,70 +10,44 @@ import { observer } from "mobx-react";
import { DrawerItem } from "../drawer";
import { Badge } from "../badge";
import type { KubeObjectDetailsProps } from "../kube-object-details";
import { PodDisruptionBudget } from "../../../common/k8s-api/endpoints";
import type { Logger } from "../../../common/logger";
import { withInjectables } from "@ogre-tools/injectable-react";
import loggerInjectable from "../../../common/logger.injectable";
import type { PodDisruptionBudget } from "../../../common/k8s-api/endpoints";
export interface PodDisruptionBudgetDetailsProps extends KubeObjectDetailsProps<PodDisruptionBudget> {
}
interface Dependencies {
logger: Logger;
}
export const PodDisruptionBudgetDetails = observer((props: PodDisruptionBudgetDetailsProps) => {
const { object: pdb } = props;
@observer
class NonInjectedPodDisruptionBudgetDetails extends React.Component<PodDisruptionBudgetDetailsProps & Dependencies> {
render() {
const { object: pdb } = this.props;
if (!pdb) {
return null;
}
if (!(pdb instanceof PodDisruptionBudget)) {
this.props.logger.error("[PodDisruptionBudgetDetails]: passed object that is not an instanceof PodDisruptionBudget", pdb);
return null;
}
const selectors = pdb.getSelectors();
return (
<div className="PdbDetails">
{selectors.length > 0 && (
<DrawerItem name="Selector" labelsOnly>
{
selectors.map(label => <Badge key={label} label={label}/>)
}
</DrawerItem>
)}
<DrawerItem name="Min Available">
{pdb.getMinAvailable()}
</DrawerItem>
<DrawerItem name="Max Unavailable">
{pdb.getMaxUnavailable()}
</DrawerItem>
<DrawerItem name="Current Healthy">
{pdb.getCurrentHealthy()}
</DrawerItem>
<DrawerItem name="Desired Healthy">
{pdb.getDesiredHealthy()}
</DrawerItem>
</div>
);
if (!pdb) {
return null;
}
}
export const PodDisruptionBudgetDetails = withInjectables<Dependencies, PodDisruptionBudgetDetailsProps>(NonInjectedPodDisruptionBudgetDetails, {
getProps: (di, props) => ({
...props,
logger: di.inject(loggerInjectable),
}),
const selectors = pdb.getSelectors();
return (
<div className="PdbDetails">
{selectors.length > 0 && (
<DrawerItem name="Selector" labelsOnly>
{selectors.map(label => <Badge key={label} label={label}/>)}
</DrawerItem>
)}
<DrawerItem name="Min Available">
{pdb.getMinAvailable()}
</DrawerItem>
<DrawerItem name="Max Unavailable">
{pdb.getMaxUnavailable()}
</DrawerItem>
<DrawerItem name="Current Healthy">
{pdb.getCurrentHealthy()}
</DrawerItem>
<DrawerItem name="Desired Healthy">
{pdb.getDesiredHealthy()}
</DrawerItem>
</div>
);
});

View File

@ -11,7 +11,7 @@ import React from "react";
import { ipcRendererOn } from "../../../common/ipc";
import type { Cluster } from "../../../common/cluster/cluster";
import type { IClassName } from "../../utils";
import { isBoolean, hasTypedProperty, isObject, isString, cssNames } from "../../utils";
import { hasTypedProperty, isObject, isString, cssNames } from "../../utils";
import { Button } from "../button";
import { Icon } from "../icon";
import { Spinner } from "../spinner";
@ -51,8 +51,8 @@ class NonInjectedClusterStatus extends React.Component<ClusterStatusProps & Depe
return this.props.entityRegistry.getById(this.cluster.id);
}
@computed get hasErrors(): boolean {
return this.authOutput.some(({ isError }) => isError);
@computed get hasErrorsOrWarnings(): boolean {
return this.authOutput.some(({ level }) => level !== "info");
}
componentDidMount() {
@ -61,7 +61,7 @@ class NonInjectedClusterStatus extends React.Component<ClusterStatusProps & Depe
if (
isObject(res)
&& hasTypedProperty(res, "message", isString)
&& hasTypedProperty(res, "isError", isBoolean)
&& hasTypedProperty(res, "level", function (val): val is KubeAuthUpdate["level"] { return ["info", "warning", "error"].includes(val as string); })
) {
this.authOutput.push(res);
} else {
@ -87,7 +87,7 @@ class NonInjectedClusterStatus extends React.Component<ClusterStatusProps & Depe
} catch (error) {
this.authOutput.push({
message: String(error),
isError: true,
level: "error",
});
} finally {
this.isReconnecting = false;
@ -102,8 +102,8 @@ class NonInjectedClusterStatus extends React.Component<ClusterStatusProps & Depe
return (
<pre>
{
this.authOutput.map(({ message, isError }, index) => (
<p key={index} className={cssNames({ error: isError })}>
this.authOutput.map(({ message, level }, index) => (
<p key={index} className={cssNames({ error: level === "error", warning: level === "warning" })}>
{message.trim()}
</p>
))
@ -113,7 +113,7 @@ class NonInjectedClusterStatus extends React.Component<ClusterStatusProps & Depe
}
renderStatusIcon() {
if (this.hasErrors) {
if (this.hasErrorsOrWarnings) {
return <Icon material="cloud_off" className={styles.icon} />;
}
@ -131,7 +131,7 @@ class NonInjectedClusterStatus extends React.Component<ClusterStatusProps & Depe
}
renderReconnectionHelp() {
if (this.hasErrors && !this.isReconnecting) {
if (this.hasErrorsOrWarnings && !this.isReconnecting) {
return (
<>
<Button

View File

@ -6,8 +6,8 @@ import { getInjectable } from "@ogre-tools/injectable";
import { kubeObjectDetailItemInjectionToken } from "../kube-object-detail-item-injection-token";
import { computed } from "mobx";
import { PodDisruptionBudgetDetails } from "../../../+config-pod-disruption-budgets";
import { kubeObjectMatchesToKindAndApiVersion } from "../kube-object-matches-to-kind-and-api-version";
import currentKubeObjectInDetailsInjectable from "../../current-kube-object-in-details.injectable";
import { PodDisruptionBudget } from "../../../../../common/k8s-api/endpoints";
const podDisruptionBudgetDetailItemInjectable = getInjectable({
id: "pod-disruption-budget-detail-item",
@ -17,7 +17,7 @@ const podDisruptionBudgetDetailItemInjectable = getInjectable({
return {
Component: PodDisruptionBudgetDetails,
enabled: computed(() => isPodDisruptionBudget(kubeObject.value.get()?.object)),
enabled: computed(() => kubeObject.value.get()?.object instanceof PodDisruptionBudget),
orderNumber: 10,
};
},
@ -25,9 +25,4 @@ const podDisruptionBudgetDetailItemInjectable = getInjectable({
injectionToken: kubeObjectDetailItemInjectionToken,
});
const isPodDisruptionBudget = kubeObjectMatchesToKindAndApiVersion(
"PodDisruptionBudget",
["policy/v1beta1"],
);
export default podDisruptionBudgetDetailItemInjectable;

View File

@ -22,6 +22,10 @@ const LensExtensions = {
Renderer: LensExtensionsRendererApi,
};
export type {
LensExtensionsRendererApi,
};
export {
React,
ReactDOM,

View File

@ -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 { Response, Headers as NodeFetchHeaders } from "node-fetch";
import type { Response, Headers as NodeFetchHeaders } from "@k8slens/node-fetch";
import { PassThrough } from "stream";
export const createMockResponseFromString = (url: string, data: string, statusCode = 200) => {

View File

@ -1,46 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import Webpack from "webpack";
import WebpackDevServer from "webpack-dev-server";
import { webpackLensRenderer } from "./renderer";
import { buildDir, webpackDevServerPort } from "./vars";
/**
* API docs:
* @url https://webpack.js.org/configuration/dev-server/
* @url https://github.com/chimurai/http-proxy-middleware
*/
const config = webpackLensRenderer({ showVars: false });
const compiler = Webpack(config);
const server = new WebpackDevServer({
setupExitSignals: true,
headers: {
"Access-Control-Allow-Origin": "*",
},
allowedHosts: "all",
host: "localhost",
port: webpackDevServerPort,
static: buildDir, // aka `devServer.contentBase` in webpack@4
hot: true,
liveReload: false,
historyApiFallback: true,
compress: true, // enable gzip for everything served
devMiddleware: {
writeToDisk: false,
index: "OpenLensDev.html",
publicPath: "/build",
},
client: {
reconnect: true,
overlay: false, // don't show warnings and errors on top of rendered app view
logging: "info",
},
}, compiler);
console.info(`[WEBPACK-DEV-SERVER]: created with options`, server.options);
server.start();

View File

@ -5,36 +5,47 @@
import esbuild from "esbuild";
import type { Options as TSLoaderOptions } from "ts-loader";
import { once } from "lodash";
const getTsLoader = (options: Partial<TSLoaderOptions>, testRegExp: RegExp) => ({
test: testRegExp,
exclude: /node_modules/,
use: {
loader: "ts-loader",
options,
},
});
const printUsingEsbuildLoader = once(() => {
console.info(`\n🚀 using esbuild-loader for ts(x)`);
});
const getEsbuildLoader = (options: Partial<TSLoaderOptions>, testRegExp: RegExp) => (printUsingEsbuildLoader(), {
test: testRegExp,
loader: "esbuild-loader",
options: {
loader: "tsx",
target: "ES2019",
implementation: esbuild,
},
});
const getTypescriptLoaderImpl = process.env.LENS_DEV_USE_ESBUILD_LOADER === "true"
? getEsbuildLoader
: getTsLoader;
// by default covers react/jsx-stuff
const defaultTestRegExp = /\.tsx?$/;
/**
* A function returning webpack ts/tsx loader
* depends on env LENS_DEV_USE_ESBUILD_LOADER to use esbuild-loader (faster) or good-old ts-loader
* @returns ts/tsx webpack loader configuration object
*/
export default function getTypescriptLoader(options: Partial<TSLoaderOptions> = {}, testRegExp?: RegExp) {
testRegExp ??= /\.tsx?$/; // by default covers react/jsx-stuff
export const getTypescriptLoader = (options?: Partial<TSLoaderOptions>, testRegExp?: RegExp) => {
options ??= {};
options.transpileOnly ??= true;
testRegExp ??= defaultTestRegExp;
if (process.env.LENS_DEV_USE_ESBUILD_LOADER === "true") {
console.info(`\n🚀 using esbuild-loader for ts(x)`);
return {
test: testRegExp,
loader: "esbuild-loader",
options: {
loader: "tsx",
target: "ES2019", // supported by >= electron@14
implementation: esbuild,
},
};
}
return {
test: testRegExp,
exclude: /node_modules/,
use: {
loader: "ts-loader",
options,
},
};
}
return getTypescriptLoaderImpl(options, testRegExp);
};

View File

@ -8,13 +8,14 @@ import path from "path";
import { DefinePlugin, optimize } from "webpack";
import main from "./main";
import renderer, { iconsAndImagesWebpackRules } from "./renderer";
import { buildDir } from "./vars";
import { buildDir, isDevelopment } from "./vars";
const rendererConfig = renderer({ showVars: false });
const mainConfig = main();
const config = [
{
...main(),
...mainConfig,
entry: {
main: path.resolve(__dirname, "..", "src", "main", "library.ts"),
},
@ -62,7 +63,7 @@ const config = [
],
},
{
...main(),
...mainConfig,
name: "lens-app-common",
entry: {
common: path.resolve(__dirname, "..", "src", "common", "library.ts"),
@ -106,7 +107,7 @@ const config = [
}),
new MiniCssExtractPlugin({
filename: "[name].css",
runtime: false,
runtime: isDevelopment,
}),
new optimize.LimitChunkCountPlugin({
maxChunks: 1,

View File

@ -7,7 +7,7 @@ import path from "path";
import type webpack from "webpack";
import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin";
import nodeExternals from "webpack-node-externals";
import getTypeScriptLoader from "./get-typescript-loader";
import { getTypescriptLoader } from "./get-typescript-loader";
import CircularDependencyPlugin from "circular-dependency-plugin";
import { iconsAndImagesWebpackRules } from "./renderer";
import type { WebpackPluginInstance } from "webpack";
@ -56,7 +56,7 @@ const main = ({ showVars = true } = {}): webpack.Configuration => {
test: /\.node$/,
use: "node-loader",
},
getTypeScriptLoader({}, /\.ts$/),
getTypescriptLoader({}, /\.ts$/),
...iconsAndImagesWebpackRules(),
],
},

View File

@ -13,7 +13,7 @@ import CircularDependencyPlugin from "circular-dependency-plugin";
import ReactRefreshWebpackPlugin from "@pmmmwh/react-refresh-webpack-plugin";
import type { WebpackPluginInstance } from "webpack";
import { DefinePlugin } from "webpack";
import getTypescriptLoader from "./get-typescript-loader";
import { getTypescriptLoader } from "./get-typescript-loader";
import { assetsFolderName, isDevelopment, rendererDir, buildDir, appName, htmlTemplate, publicPath, sassCommonVars, additionalExternals } from "./vars";
import { platform } from "process";
@ -65,7 +65,6 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura
},
externals: [
{
"node-fetch": "commonjs node-fetch",
"win-ca": "commonjs win-ca",
},
...additionalExternals,
@ -176,9 +175,7 @@ export interface CssModulesWebpackRuleOptions {
* Import CSS or SASS styles with modules support (*.module.scss)
*/
export function cssModulesWebpackRule({ styleLoader }: CssModulesWebpackRuleOptions = {}): webpack.RuleSetRule {
styleLoader ??= isDevelopment
? "style-loader"
: MiniCssExtractPlugin.loader;
styleLoader ??= MiniCssExtractPlugin.loader;
return {
test: /\.s?css$/,

View File

@ -36,14 +36,7 @@
resolved "https://registry.yarnpkg.com/@async-fn/jest/-/jest-1.6.4.tgz#202f6a070847123e81c7c6bd5bee5a8f12ebbd40"
integrity sha512-m3T/m6a39f5dbqFj79BGCqudkm42McgMXD7M0ZorKeqqdAbNazay7t+VDOz5qqFHO12frFbbhAB5GnFPoGADPA==
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.8.3":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==
dependencies:
"@babel/highlight" "^7.16.0"
"@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7":
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==
@ -221,7 +214,7 @@
dependencies:
"@babel/types" "^7.16.7"
"@babel/helper-validator-identifier@^7.15.7", "@babel/helper-validator-identifier@^7.16.7":
"@babel/helper-validator-identifier@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
@ -249,15 +242,6 @@
"@babel/traverse" "^7.18.2"
"@babel/types" "^7.18.2"
"@babel/highlight@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
dependencies:
"@babel/helper-validator-identifier" "^7.15.7"
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/highlight@^7.16.7":
version "7.17.9"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.17.9.tgz#61b2ee7f32ea0454612def4fccdae0de232b73e3"
@ -1284,29 +1268,27 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
"@kubernetes/client-node@^0.18.0":
version "0.18.0"
resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.18.0.tgz#b1002f3c19fb7509ce521ea78f500589f8e3e047"
integrity sha512-Mp6q0OkZQBp+HslIgvHYpsPJk8z6mch231QWtIZQHvs+PaTE6mkUfusYE8fNw3jMjru5mVO/JDz6PTjB9YT2rQ==
"@kubernetes/client-node@^0.18.1":
version "0.18.1"
resolved "https://registry.yarnpkg.com/@kubernetes/client-node/-/client-node-0.18.1.tgz#58d864c8f584efd0f8670f6c46bb8e9d5abd58f6"
integrity sha512-F3JiK9iZnbh81O/da1tD0h8fQMi/MDttWc/JydyUVnjPEom55wVfnpl4zQ/sWD4uKB8FlxYRPiLwV2ZXB+xPKw==
dependencies:
"@types/js-yaml" "^4.0.1"
"@types/node" "^10.12.0"
"@types/node" "^18.11.17"
"@types/request" "^2.47.1"
"@types/ws" "^6.0.1"
"@types/ws" "^8.5.3"
byline "^5.0.0"
execa "5.0.0"
isomorphic-ws "^4.0.1"
isomorphic-ws "^5.0.0"
js-yaml "^4.1.0"
jsonpath-plus "^0.19.0"
jsonpath-plus "^7.2.0"
request "^2.88.0"
rfc4648 "^1.3.0"
shelljs "^0.8.5"
stream-buffers "^3.0.2"
tar "^6.1.11"
tmp-promise "^3.0.2"
tslib "^2.4.1"
underscore "^1.13.6"
ws "^7.3.1"
ws "^8.11.0"
optionalDependencies:
openid-client "^5.3.0"
@ -1777,10 +1759,10 @@
"@sentry/types" "6.19.7"
tslib "^1.9.3"
"@side/jest-runtime@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@side/jest-runtime/-/jest-runtime-1.0.1.tgz#29c3874570f1a6bbdeea86e4bc60eaef385e3af3"
integrity sha512-gDrS+Z9xu3tue2ighChftPPpA5qU26+p5iBNymaXh8kFhFecsokZdwyo+/wNu8QNcbyEnlB+DZAGkpG2Mm1jWA==
"@side/jest-runtime@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@side/jest-runtime/-/jest-runtime-1.1.0.tgz#30c0d005231e887bb81ac2ab8611076b5e592bde"
integrity sha512-KikALXowNWyOxn/zdy4AUgkYq/1hASkOEEP0+bcCDv5L3KJNwDw8kmzBcx7sljnwV8yi2cLGzt9QH9EjwA9TKg==
"@sideway/address@^4.1.3":
version "4.1.4"
@ -1845,71 +1827,71 @@
slash "3.0.0"
source-map "^0.7.3"
"@swc/core-darwin-arm64@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.27.tgz#247b275d505c2462ce08cca4e322becbca8e428a"
integrity sha512-IKlxkhEy99CnP9nduaf5IJWIFcr6D5cZCjYmCs7nWkjMV+aAieyDO9AX4LT8AcHy6CF7ByOX7SKoqk+gVMAaKw==
"@swc/core-darwin-arm64@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.28.tgz#3ab15dd6f0ede5b3c7d6ed557a26c0fad34ee5c9"
integrity sha512-f1ph5DDIOX6bvjhlOuWz8ZDiTghhq144Sy9gaRi+DjK3gdnftc4p5AyZHA4Xb03MZ+fd0mj8q6/znco5aBMi1A==
"@swc/core-darwin-x64@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.27.tgz#11090424c9bfd0d3e799abb06c1fa6a07abf5ed9"
integrity sha512-MtabZIhFf/dL3vs6UMbd+vJsjIkm2NaFqulGV0Jofy2bfVZPTj/b5pXeOlUsTWy7JcH1uixjdx4RvJRyvqJxQA==
"@swc/core-darwin-x64@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.28.tgz#e0eaa0eb763bc7def581df93b1a5df1249eb5528"
integrity sha512-5dB5Z4Ry45UTXXAxhwagCYfh57njffkdIJkjid1f+Qt4i7cOznOaIiD4wobGD7xHCATEcs8F23yWkAmvrbacew==
"@swc/core-linux-arm-gnueabihf@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.27.tgz#a41b40e056ed0887686e04a30b395521fe3f2d47"
integrity sha512-XELMoGcUTAkk+G4buwIIhu6AIr1U418Odt22HUW8+ZvV+Wty2ICgR/myOIhM3xMb6U2L8ay+evMqoVNMQ0RRTg==
"@swc/core-linux-arm-gnueabihf@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.28.tgz#f7038e60bddebc6b0c0aa444c50157fe4908fb58"
integrity sha512-VmtAQAENJ5SHBXTKxXNlnnM34xGOtJpHYva83zeZM/2epdoz1BJ6Ny3gTBXDftaWgAj2SRwVIjMR3/c71aJysQ==
"@swc/core-linux-arm64-gnu@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.27.tgz#61705b0d534472a9dbde575594c61ef1377d0075"
integrity sha512-O6vtT6bnrVR9PzEIuA5U7tIfYo7bv97H9K9Vqy2oyHNeGN0H36DKwS4UqPreHtziXNF5+7ubdUYUkrG/j8UnUQ==
"@swc/core-linux-arm64-gnu@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.28.tgz#6e3013176c4cc5dd006c848911e3bccaf1fa77dd"
integrity sha512-KIJ1SHGbusM6W2rxue1f+IN/iuzmspgMY9qP/qW5Z43Mm9mrHdzDmhsMoEH1y2gPUsu/ZZnkXlODJ0M0454JNQ==
"@swc/core-linux-arm64-musl@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.27.tgz#4fb86dcf70b7fc1aba51d82bba00bb2c4134a980"
integrity sha512-Oa0E1i7dOTWpaEZumKoNbTE/Ap+da6nlhqKVUdYrFDrOBi25tz76SdxZIyvAszzmgY89b5yd1naourKmkPXpww==
"@swc/core-linux-arm64-musl@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.28.tgz#01896d81f967104fb851534962dd344252d85025"
integrity sha512-Zz2DZj8ncSvVEAsol8gtoXrVLP8e+IYSx6o8txYVR0p0pviJBzeuYGaLe5sbQdQnVVS2M5N90LX28P6/mQb6sQ==
"@swc/core-linux-x64-gnu@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.27.tgz#691cc341f8dd7f93a8e01044a2ad8b0e7111d65c"
integrity sha512-S3v9H8oL2a8Ur6AjQyhkC6HfBVPOxKMdBhcZmdNuVgEUHbHdbf/Lka85F9IOYXEarMn0FtQw3ywowS22O9L5Uw==
"@swc/core-linux-x64-gnu@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.28.tgz#03d9b0171267ccc5d0efd2a939150f5d1da550ae"
integrity sha512-Za3uowhcP74qSCNqjZLBx3nAmjIFYNbB0nGBKwkLBopbMcpO0BjvnsdzmoWqv2Uq41vaeVk/o9vATQMojfHHQg==
"@swc/core-linux-x64-musl@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.27.tgz#a3e1c98513d6e8594c612ab3a671f10e2644dc2e"
integrity sha512-6DDkdXlOADpwICFZTRphCR+cIeS8aEYh4NlyzBito0mOWwIIdfCgALzhkTQOzTOkcD42bP97CIoZ97hqV/puOg==
"@swc/core-linux-x64-musl@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.28.tgz#6badfc87d94b7891c11aa71496498d2ff29535db"
integrity sha512-i3BAkmrf19VXybbjuS9Jnlnx5Ie4vukLMCQRfXCQqIqaiSw3QzubjolYo07sGtzoVI3nBscDt3i8T+oxTPOMkw==
"@swc/core-win32-arm64-msvc@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.27.tgz#70c173f78d3dfd97a0d99374d8f6d55b6fa1c4ef"
integrity sha512-baxfH4AbEcaTNo08wxV0W6hiMXwVCxPS4qc0amHpXPti92unvSqeDR1W3C9GjHqzXlWtmCRsq8Ww1pal6ZVLrw==
"@swc/core-win32-arm64-msvc@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.28.tgz#2441d2cdbc313618332de014be0c6c3573931b62"
integrity sha512-DdNxKP/P0/OFqX1dtl9Ubrd567QPMSeJvp9iDtMdgCBWN2N6HXvyMj623WIA0y9FIcA7wexz0Hh3gS+G9Jof+Q==
"@swc/core-win32-ia32-msvc@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.27.tgz#f34d40710da7939ea32c9a3a4334581468ae09aa"
integrity sha512-7iLJnH71k5qCwxv9NcM/P7nIEzTsC7r1sIiQW6bu+CpC8qZvwl0PS+XvQRlLly2gCZM+Le98tksYG14MEh+Hrw==
"@swc/core-win32-ia32-msvc@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.28.tgz#82319fcff87289e3e9439dd76524a7bdfe58f5fa"
integrity sha512-/jZWBIgaNkKTlKiZ7DXmMJzW0n1ychDKS1bYRuNLrtTRthMP5M3LRZXITz0AcvPl0mIA0IXeMQbE4ZMUc7LAFg==
"@swc/core-win32-x64-msvc@1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.27.tgz#f3b131d952808569d99dd4851e95910667743bd5"
integrity sha512-mFM907PDw/jrQ44+TRjIVGEOy2Mu06mMMz0HPMFuRsBzl5t0Kajp3vmn8FkkpS9wH5982VPi6hPYVTb7QJo5Qg==
"@swc/core-win32-x64-msvc@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.28.tgz#a2067da2f3f4f95ef1b05eb86941d0609a66e9c6"
integrity sha512-HKhE0LznEwTP/qi6EVclmJzfNdykzuK6sjYMTjcDqNJOuuRNMu+IJzPzCPuakgljymWGFmddnuuubd9Y+kl3eg==
"@swc/core@^1.3.27":
version "1.3.27"
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.27.tgz#189da5fd132beba28106f5e5fcf43ce127c800dc"
integrity sha512-praRNgpeYGvwDIm/Cl6JU+yHMvwVraL0U6ejMgGyzvpcm1FVsZd1/EYXGqzbBJ0ALv7Gx4eK56h4GnwV6d4L0w==
"@swc/core@^1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.28.tgz#e0fc1fd15b2e7e01d0f16d55eb60b74e65fb1025"
integrity sha512-yzc61HbAIjHeOYTUW/IgXAywlSviMFymnUiLY7dNUELGHjMVxSp0XnIlPQN4v5UekYbwLEV8+KChaoQRACiQCw==
optionalDependencies:
"@swc/core-darwin-arm64" "1.3.27"
"@swc/core-darwin-x64" "1.3.27"
"@swc/core-linux-arm-gnueabihf" "1.3.27"
"@swc/core-linux-arm64-gnu" "1.3.27"
"@swc/core-linux-arm64-musl" "1.3.27"
"@swc/core-linux-x64-gnu" "1.3.27"
"@swc/core-linux-x64-musl" "1.3.27"
"@swc/core-win32-arm64-msvc" "1.3.27"
"@swc/core-win32-ia32-msvc" "1.3.27"
"@swc/core-win32-x64-msvc" "1.3.27"
"@swc/core-darwin-arm64" "1.3.28"
"@swc/core-darwin-x64" "1.3.28"
"@swc/core-linux-arm-gnueabihf" "1.3.28"
"@swc/core-linux-arm64-gnu" "1.3.28"
"@swc/core-linux-arm64-musl" "1.3.28"
"@swc/core-linux-x64-gnu" "1.3.28"
"@swc/core-linux-x64-musl" "1.3.28"
"@swc/core-win32-arm64-msvc" "1.3.28"
"@swc/core-win32-ia32-msvc" "1.3.28"
"@swc/core-win32-x64-msvc" "1.3.28"
"@swc/jest@^0.2.24":
version "0.2.24"
@ -2118,13 +2100,6 @@
"@types/node" "*"
source-map "^0.6.0"
"@types/cli-progress@^3.11.0":
version "3.11.0"
resolved "https://registry.yarnpkg.com/@types/cli-progress/-/cli-progress-3.11.0.tgz#ec79df99b26757c3d1c7170af8422e0fc95eef7e"
integrity sha512-XhXhBv1R/q2ahF3BM7qT5HLzJNlIL0wbcGyZVjqOTqAybAnsLisd7gy1UCyIqpL+5Iv6XhlSyzjLCnI2sIdbCg==
dependencies:
"@types/node" "*"
"@types/color-convert@*":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-2.0.0.tgz#8f5ee6b9e863dcbee5703f5a517ffb13d3ea4e22"
@ -2262,13 +2237,6 @@
dependencies:
"@types/node" "*"
"@types/gunzip-maybe@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@types/gunzip-maybe/-/gunzip-maybe-1.4.0.tgz#9410fd15ff68eca8907b7b9198e63e2a7c14d511"
integrity sha512-dFP9GrYAR9KhsjTkWJ8q8Gsfql75YIKcg9DuQOj/IrlPzR7W+1zX+cclw1McV82UXAQ+Lpufvgk3e9bC8+HzgA==
dependencies:
"@types/node" "*"
"@types/hapi__call@^9.0.0":
version "9.0.0"
resolved "https://registry.yarnpkg.com/@types/hapi__call/-/hapi__call-9.0.0.tgz#17e287ce9333c59716b194720eea9f12e63a72f2"
@ -2377,7 +2345,7 @@
resolved "https://registry.yarnpkg.com/@types/json-buffer/-/json-buffer-3.0.0.tgz#85c1ff0f0948fc159810d4b5be35bf8c20875f64"
integrity sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==
"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
version "7.0.9"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
@ -2452,15 +2420,10 @@
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
"@types/node@*":
version "17.0.24"
resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.24.tgz#20ba1bf69c1b4ab405c7a01e950c4f446b05029f"
integrity sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==
"@types/node@^10.12.0":
version "10.17.60"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b"
integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==
"@types/node@*", "@types/node@^18.11.17":
version "18.11.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==
"@types/node@^16.11.26", "@types/node@^16.18.11":
version "16.18.11"
@ -2698,13 +2661,6 @@
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310"
integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ==
"@types/tar-stream@^2.2.2":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/tar-stream/-/tar-stream-2.2.2.tgz#be9d0be9404166e4b114151f93e8442e6ab6fb1d"
integrity sha512-1AX+Yt3icFuU6kxwmPakaiGrJUwG44MpuiqPg4dSolRFk6jmvs4b3IbUol9wKDLIgU76gevn3EwE8y/DkSJCZQ==
dependencies:
"@types/node" "*"
"@types/tar@^6.1.3":
version "6.1.3"
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-6.1.3.tgz#46a2ce7617950c4852dfd7e9cd41aa8161b9d750"
@ -2819,17 +2775,10 @@
tapable "^2.2.0"
webpack "^5"
"@types/ws@^6.0.1":
version "6.0.4"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.4.tgz#7797707c8acce8f76d8c34b370d4645b70421ff1"
integrity sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==
dependencies:
"@types/node" "*"
"@types/ws@^8.5.1":
version "8.5.3"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d"
integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==
"@types/ws@^8.5.1", "@types/ws@^8.5.3":
version "8.5.4"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5"
integrity sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==
dependencies:
"@types/node" "*"
@ -2859,14 +2808,14 @@
dependencies:
"@types/yargs-parser" "*"
"@typescript-eslint/eslint-plugin@^5.48.2":
version "5.48.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.2.tgz#112e6ae1e23a1dc8333ce82bb9c65c2608b4d8a3"
integrity sha512-sR0Gja9Ky1teIq4qJOl0nC+Tk64/uYdX+mi+5iB//MH8gwyx8e3SOyhEzeLZEFEEfCaLf8KJq+Bd/6je1t+CAg==
"@typescript-eslint/eslint-plugin@^5.49.0":
version "5.49.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.49.0.tgz#d0b4556f0792194bf0c2fb297897efa321492389"
integrity sha512-IhxabIpcf++TBaBa1h7jtOWyon80SXPRLDq0dVz5SLFC/eW6tofkw/O7Ar3lkx5z5U6wzbKDrl2larprp5kk5Q==
dependencies:
"@typescript-eslint/scope-manager" "5.48.2"
"@typescript-eslint/type-utils" "5.48.2"
"@typescript-eslint/utils" "5.48.2"
"@typescript-eslint/scope-manager" "5.49.0"
"@typescript-eslint/type-utils" "5.49.0"
"@typescript-eslint/utils" "5.49.0"
debug "^4.3.4"
ignore "^5.2.0"
natural-compare-lite "^1.4.0"
@ -2874,72 +2823,72 @@
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/parser@^5.48.2":
version "5.48.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.48.2.tgz#c9edef2a0922d26a37dba03be20c5fff378313b3"
integrity sha512-38zMsKsG2sIuM5Oi/olurGwYJXzmtdsHhn5mI/pQogP+BjYVkK5iRazCQ8RGS0V+YLk282uWElN70zAAUmaYHw==
"@typescript-eslint/parser@^5.49.0":
version "5.49.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.49.0.tgz#d699734b2f20e16351e117417d34a2bc9d7c4b90"
integrity sha512-veDlZN9mUhGqU31Qiv2qEp+XrJj5fgZpJ8PW30sHU+j/8/e5ruAhLaVDAeznS7A7i4ucb/s8IozpDtt9NqCkZg==
dependencies:
"@typescript-eslint/scope-manager" "5.48.2"
"@typescript-eslint/types" "5.48.2"
"@typescript-eslint/typescript-estree" "5.48.2"
"@typescript-eslint/scope-manager" "5.49.0"
"@typescript-eslint/types" "5.49.0"
"@typescript-eslint/typescript-estree" "5.49.0"
debug "^4.3.4"
"@typescript-eslint/scope-manager@5.48.2":
version "5.48.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.48.2.tgz#bb7676cb78f1e94921eaab637a4b5d596f838abc"
integrity sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw==
"@typescript-eslint/scope-manager@5.49.0":
version "5.49.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.49.0.tgz#81b5d899cdae446c26ddf18bd47a2f5484a8af3e"
integrity sha512-clpROBOiMIzpbWNxCe1xDK14uPZh35u4QaZO1GddilEzoCLAEz4szb51rBpdgurs5k2YzPtJeTEN3qVbG+LRUQ==
dependencies:
"@typescript-eslint/types" "5.48.2"
"@typescript-eslint/visitor-keys" "5.48.2"
"@typescript-eslint/types" "5.49.0"
"@typescript-eslint/visitor-keys" "5.49.0"
"@typescript-eslint/type-utils@5.48.2":
version "5.48.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.48.2.tgz#7d3aeca9fa37a7ab7e3d9056a99b42f342c48ad7"
integrity sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew==
"@typescript-eslint/type-utils@5.49.0":
version "5.49.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.49.0.tgz#8d5dcc8d422881e2ccf4ebdc6b1d4cc61aa64125"
integrity sha512-eUgLTYq0tR0FGU5g1YHm4rt5H/+V2IPVkP0cBmbhRyEmyGe4XvJ2YJ6sYTmONfjmdMqyMLad7SB8GvblbeESZA==
dependencies:
"@typescript-eslint/typescript-estree" "5.48.2"
"@typescript-eslint/utils" "5.48.2"
"@typescript-eslint/typescript-estree" "5.49.0"
"@typescript-eslint/utils" "5.49.0"
debug "^4.3.4"
tsutils "^3.21.0"
"@typescript-eslint/types@5.48.2":
version "5.48.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.48.2.tgz#635706abb1ec164137f92148f06f794438c97b8e"
integrity sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA==
"@typescript-eslint/types@5.49.0":
version "5.49.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.49.0.tgz#ad66766cb36ca1c89fcb6ac8b87ec2e6dac435c3"
integrity sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==
"@typescript-eslint/typescript-estree@5.48.2":
version "5.48.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.2.tgz#6e206b462942b32383582a6c9251c05021cc21b0"
integrity sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg==
"@typescript-eslint/typescript-estree@5.49.0":
version "5.49.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz#ebd6294c0ea97891fce6af536048181e23d729c8"
integrity sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==
dependencies:
"@typescript-eslint/types" "5.48.2"
"@typescript-eslint/visitor-keys" "5.48.2"
"@typescript-eslint/types" "5.49.0"
"@typescript-eslint/visitor-keys" "5.49.0"
debug "^4.3.4"
globby "^11.1.0"
is-glob "^4.0.3"
semver "^7.3.7"
tsutils "^3.21.0"
"@typescript-eslint/utils@5.48.2":
version "5.48.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.48.2.tgz#3777a91dcb22b8499a25519e06eef2e9569295a3"
integrity sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow==
"@typescript-eslint/utils@5.49.0":
version "5.49.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.49.0.tgz#1c07923bc55ff7834dfcde487fff8d8624a87b32"
integrity sha512-cPJue/4Si25FViIb74sHCLtM4nTSBXtLx1d3/QT6mirQ/c65bV8arBEebBJJizfq8W2YyMoPI/WWPFWitmNqnQ==
dependencies:
"@types/json-schema" "^7.0.9"
"@types/semver" "^7.3.12"
"@typescript-eslint/scope-manager" "5.48.2"
"@typescript-eslint/types" "5.48.2"
"@typescript-eslint/typescript-estree" "5.48.2"
"@typescript-eslint/scope-manager" "5.49.0"
"@typescript-eslint/types" "5.49.0"
"@typescript-eslint/typescript-estree" "5.49.0"
eslint-scope "^5.1.1"
eslint-utils "^3.0.0"
semver "^7.3.7"
"@typescript-eslint/visitor-keys@5.48.2":
version "5.48.2"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz#c247582a0bcce467461d7b696513bf9455000060"
integrity sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ==
"@typescript-eslint/visitor-keys@5.49.0":
version "5.49.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz#2561c4da3f235f5c852759bf6c5faec7524f90fe"
integrity sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==
dependencies:
"@typescript-eslint/types" "5.48.2"
"@typescript-eslint/types" "5.49.0"
eslint-visitor-keys "^3.3.0"
"@webassemblyjs/ast@1.11.1":
@ -3854,13 +3803,6 @@ browser-process-hrtime@^1.0.0:
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
browserify-zlib@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d"
integrity sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=
dependencies:
pako "~0.2.0"
browserslist@^4.14.5, browserslist@^4.20.2:
version "4.20.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf"
@ -4198,7 +4140,7 @@ chartjs-color@^2.1.0:
chartjs-color-string "^0.6.0"
color-convert "^1.9.3"
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.2, chokidar@^3.5.2, chokidar@^3.5.3:
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.2, chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
@ -4289,13 +4231,6 @@ cli-cursor@^3.1.0:
dependencies:
restore-cursor "^3.1.0"
cli-progress@^3.11.2:
version "3.11.2"
resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.11.2.tgz#f8c89bd157e74f3f2c43bcfb3505670b4d48fc77"
integrity sha512-lCPoS6ncgX4+rJu5bS3F/iCz17kZ9MPZ6dpuTtI0KXKABkhyXIdYB3Inby1OpaGti3YlI3EeEkM9AuWpelJrVA==
dependencies:
string-width "^4.2.3"
cli-table3@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.2.tgz#aaf5df9d8b5bf12634dc8b3040806a0c07120d2a"
@ -4684,10 +4619,10 @@ cosmiconfig@^6.0.0:
path-type "^4.0.0"
yaml "^1.7.2"
cosmiconfig@^7.0.0:
version "7.0.1"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d"
integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==
cosmiconfig@^7.0.0, cosmiconfig@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6"
integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==
dependencies:
"@types/parse-json" "^4.0.0"
import-fresh "^3.2.1"
@ -4877,11 +4812,6 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
data-uri-to-buffer@^4.0.0:
version "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"
@ -5393,16 +5323,6 @@ duplexer3@^0.1.4:
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
duplexify@^3.5.0, duplexify@^3.6.0:
version "3.7.1"
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309"
integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==
dependencies:
end-of-stream "^1.0.0"
inherits "^2.0.1"
readable-stream "^2.0.0"
stream-shift "^1.0.0"
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@ -6069,21 +5989,6 @@ events@^3.2.0:
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
execa@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376"
integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==
dependencies:
cross-spawn "^7.0.3"
get-stream "^6.0.0"
human-signals "^2.1.0"
is-stream "^2.0.0"
merge-stream "^2.0.0"
npm-run-path "^4.0.1"
onetime "^5.1.2"
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
execa@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
@ -6322,14 +6227,6 @@ fecha@^4.2.0:
resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd"
integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==
fetch-blob@^3.1.2, fetch-blob@^3.1.4:
version "3.2.0"
resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9"
integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==
dependencies:
node-domexception "^1.0.0"
web-streams-polyfill "^3.0.3"
figures@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af"
@ -6542,24 +6439,23 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
fork-ts-checker-webpack-plugin@^6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340"
integrity sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA==
fork-ts-checker-webpack-plugin@^7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.3.0.tgz#a9c984a018493962360d7c7e77a67b44a2d5f3aa"
integrity sha512-IN+XTzusCjR5VgntYFgxbxVx3WraPRnKehBFrf00cMSrtUuW9MsG9dhL6MWpY6MkjC3wVwoujfCDgZZCQwbswA==
dependencies:
"@babel/code-frame" "^7.8.3"
"@types/json-schema" "^7.0.5"
chalk "^4.1.0"
chokidar "^3.4.2"
cosmiconfig "^6.0.0"
"@babel/code-frame" "^7.16.7"
chalk "^4.1.2"
chokidar "^3.5.3"
cosmiconfig "^7.0.1"
deepmerge "^4.2.2"
fs-extra "^9.0.0"
glob "^7.1.6"
memfs "^3.1.2"
fs-extra "^10.0.0"
memfs "^3.4.1"
minimatch "^3.0.4"
schema-utils "2.7.0"
semver "^7.3.2"
tapable "^1.0.0"
node-abort-controller "^3.0.1"
schema-utils "^3.1.1"
semver "^7.3.5"
tapable "^2.2.1"
form-data@^2.5.0:
version "2.5.1"
@ -6597,13 +6493,6 @@ form-data@~2.3.2:
combined-stream "^1.0.6"
mime-types "^2.1.12"
formdata-polyfill@^4.0.10:
version "4.0.10"
resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423"
integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==
dependencies:
fetch-blob "^3.1.2"
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@ -6662,7 +6551,7 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0:
dependencies:
minipass "^3.0.0"
fs-monkey@1.0.3, fs-monkey@^1.0.3:
fs-monkey@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3"
integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==
@ -6834,7 +6723,7 @@ glob-to-regexp@^0.4.1:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
@ -7023,18 +6912,6 @@ gulp-header@^1.7.1:
lodash.template "^4.4.0"
through2 "^2.0.0"
gunzip-maybe@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz#b913564ae3be0eda6f3de36464837a9cd94b98ac"
integrity sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==
dependencies:
browserify-zlib "^0.1.4"
is-deflate "^1.0.0"
is-gzip "^1.0.0"
peek-stream "^1.1.0"
pumpify "^1.3.3"
through2 "^2.0.3"
handle-thing@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
@ -7565,11 +7442,6 @@ internal-slot@^1.0.3:
has "^1.0.3"
side-channel "^1.0.4"
interpret@^1.0.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==
interpret@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9"
@ -7685,11 +7557,6 @@ is-date-object@^1.0.1:
dependencies:
has-tostringtag "^1.0.0"
is-deflate@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-deflate/-/is-deflate-1.0.0.tgz#c862901c3c161fb09dac7cdc7e784f80e98f2f14"
integrity sha1-yGKQHDwWH7CdrHzcfnhPgOmPLxQ=
is-docker@^2.0.0, is-docker@^2.1.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
@ -7739,11 +7606,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
is-gzip@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-gzip/-/is-gzip-1.0.0.tgz#6ca8b07b99c77998025900e555ced8ed80879a83"
integrity sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=
is-in-browser@^1.0.2, is-in-browser@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835"
@ -7956,10 +7818,10 @@ isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
isomorphic-ws@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc"
integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==
isomorphic-ws@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf"
integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==
isstream@~0.1.2:
version "0.1.2"
@ -8637,10 +8499,10 @@ jsonparse@^1.3.1:
resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==
jsonpath-plus@^0.19.0:
version "0.19.0"
resolved "https://registry.yarnpkg.com/jsonpath-plus/-/jsonpath-plus-0.19.0.tgz#b901e57607055933dc9a8bef0cc25160ee9dd64c"
integrity sha512-GSVwsrzW9LsA5lzsqe4CkuZ9wp+kxBb2GwNniaWzI2YFn5Ig42rSW8ZxVpWXaAfakXNrx5pgY5AbQq7kzX29kg==
jsonpath-plus@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/jsonpath-plus/-/jsonpath-plus-7.2.0.tgz#7ad94e147b3ed42f7939c315d2b9ce490c5a3899"
integrity sha512-zBfiUPM5nD0YZSBT/o/fbCUlCcepMIdP0CJZxM1+KgA4f2T206f6VAg9e7mX35+KlMaIc5qXW34f3BnwJ3w+RA==
jsprim@^1.2.2:
version "1.4.2"
@ -9334,14 +9196,7 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
memfs@^3.1.2, memfs@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305"
integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==
dependencies:
fs-monkey "1.0.3"
memfs@^3.4.13:
memfs@^3.4.1, memfs@^3.4.13:
version "3.4.13"
resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.13.tgz#248a8bd239b3c240175cd5ec548de5227fc4f345"
integrity sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==
@ -9761,6 +9616,11 @@ node-abi@^3.3.0:
dependencies:
semver "^7.3.5"
node-abort-controller@^3.0.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548"
integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==
node-addon-api@^1.6.3:
version "1.7.2"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d"
@ -9771,20 +9631,6 @@ node-addon-api@^5.0.0:
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.0.0.tgz#7d7e6f9ef89043befdb20c1989c905ebde18c501"
integrity sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==
node-domexception@^1.0.0:
version "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@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.0.tgz#37e71db4ecc257057af828d523a7243d651d91e4"
integrity sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==
dependencies:
data-uri-to-buffer "^4.0.0"
fetch-blob "^3.1.4"
formdata-polyfill "^4.0.10"
node-forge@^1, node-forge@^1.2.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
@ -10475,11 +10321,6 @@ pacote@^13.0.3, pacote@^13.6.1, pacote@^13.6.2:
ssri "^9.0.0"
tar "^6.1.11"
pako@~0.2.0:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
integrity sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=
pako@~1.0.2:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
@ -10594,15 +10435,6 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
peek-stream@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67"
integrity sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==
dependencies:
buffer-from "^1.0.0"
duplexify "^3.5.0"
through2 "^2.0.3"
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
@ -10669,17 +10501,17 @@ pkg-up@^3.1.0:
dependencies:
find-up "^3.0.0"
playwright-core@1.29.2:
version "1.29.2"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.29.2.tgz#2e8347e7e8522409f22b244e600e703b64022406"
integrity sha512-94QXm4PMgFoHAhlCuoWyaBYKb92yOcGVHdQLoxQ7Wjlc7Flg4aC/jbFW7xMR52OfXMVkWicue4WXE7QEegbIRA==
playwright-core@1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.30.0.tgz#de987cea2e86669e3b85732d230c277771873285"
integrity sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g==
playwright@^1.29.2:
version "1.29.2"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.29.2.tgz#d6a0a3e8e44f023f7956ed19ffa8af915a042769"
integrity sha512-hKBYJUtdmYzcjdhYDkP9WGtORwwZBBKAW8+Lz7sr0ZMxtJr04ASXVzH5eBWtDkdb0c3LLFsehfPBTRfvlfKJOA==
playwright@^1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.30.0.tgz#b1d7be2d45d97fbb59f829f36f521f12010fe072"
integrity sha512-ENbW5o75HYB3YhnMTKJLTErIBExrSlX2ZZ1C/FzmHjUYIfxj/UnI+DWpQr992m+OQVSg0rCExAOlRwB+x+yyIg==
dependencies:
playwright-core "1.29.2"
playwright-core "1.30.0"
plist@^3.0.1, plist@^3.0.4:
version "3.0.5"
@ -11009,14 +10841,6 @@ pstree.remy@^1.1.8:
resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
pump@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
@ -11025,15 +10849,6 @@ pump@^3.0.0:
end-of-stream "^1.1.0"
once "^1.3.1"
pumpify@^1.3.3:
version "1.5.1"
resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce"
integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==
dependencies:
duplexify "^3.6.0"
inherits "^2.0.3"
pump "^2.0.0"
punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
@ -11391,13 +11206,6 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
dependencies:
resolve "^1.1.6"
rechoir@^0.7.0:
version "0.7.1"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686"
@ -11564,7 +11372,7 @@ resolve.exports@^1.1.0:
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9"
integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==
resolve@^1.1.6, resolve@^1.1.7, resolve@^1.12.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.9.0:
resolve@^1.1.7, resolve@^1.12.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.9.0:
version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
@ -11752,15 +11560,6 @@ scheduler@^0.20.2:
loose-envify "^1.1.0"
object-assign "^4.1.1"
schema-utils@2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7"
integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==
dependencies:
"@types/json-schema" "^7.0.4"
ajv "^6.12.2"
ajv-keywords "^3.4.1"
schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281"
@ -11985,15 +11784,6 @@ shell-quote@^1.7.3:
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123"
integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==
shelljs@^0.8.5:
version "0.8.5"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c"
integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
shiki@^0.12.1:
version "0.12.1"
resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.12.1.tgz#26fce51da12d055f479a091a5307470786f300cd"
@ -12345,11 +12135,6 @@ stream-buffers@^3.0.2:
resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-3.0.2.tgz#5249005a8d5c2d00b3a32e6e0a6ea209dc4f3521"
integrity sha512-DQi1h8VEBA/lURbSwFtEHnSTb9s2/pwLEaFuNhXwy1Dx3Sa0lOuYT2yNUr4/j2fs8oCAMANtrZ5OrPZtyVs3MQ==
stream-shift@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
@ -12631,12 +12416,7 @@ tailwindcss@^3.2.4:
quick-lru "^5.1.1"
resolve "^1.22.1"
tapable@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0:
tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
@ -12664,7 +12444,7 @@ tar-stream@^1.5.2:
to-buffer "^1.1.1"
xtend "^4.0.0"
tar-stream@^2.1.4, tar-stream@^2.2.0:
tar-stream@^2.1.4:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
@ -12777,7 +12557,7 @@ text-table@^0.2.0, text-table@~0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
through2@^2.0.0, through2@^2.0.3:
through2@^2.0.0:
version "2.0.5"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
@ -13473,11 +13253,6 @@ wcwidth@^1.0.0:
dependencies:
defaults "^1.0.3"
web-streams-polyfill@^3.0.3:
version "3.2.1"
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"
@ -13789,12 +13564,12 @@ 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.4.6:
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.11.0, ws@^8.12.0, ws@^8.2.3, ws@^8.4.2:
version "8.12.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.0.tgz#485074cc392689da78e1828a9ff23585e06cddd8"
integrity sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==

2
packages/download-binaries/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
dist/
node_modules/

View File

@ -0,0 +1,37 @@
{
"name": "@k8slens/download-binaries",
"version": "6.4.0-beta.8",
"description": "CLI for downloading configured versions of the bundled versions of CLIs",
"main": "dist/index.mjs",
"license": "MIT",
"scripts": {
"clean": "rm -rf dist/",
"build": "swc ./src/index.ts -o ./dist/index.mjs"
},
"bin": "./dist/index.mjs",
"files": [
"dist"
],
"private": false,
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"arg": "^5.0.2",
"cli-progress": "^3.11.2",
"gunzip-maybe": "^1.4.2",
"node-fetch": "^3.3.0",
"tar-stream": "^3.0.0",
"zod": "^3.20.2"
},
"devDependencies": {
"@swc/cli": "^0.1.59",
"@swc/core": "^1.3.28",
"@types/cli-progress": "^3.11.0",
"@types/gunzip-maybe": "^1.4.0",
"@types/node": "^16.18.11",
"@types/semver": "^7.3.13",
"@types/tar-stream": "^2.2.2"
}
}

View File

@ -1,26 +1,44 @@
#!/usr/bin/env node
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import packageInfo from "../package.json";
import type { FileHandle } from "fs/promises";
import { open } from "fs/promises";
import type { WriteStream } from "fs-extra";
import { constants, ensureDir, unlink } from "fs-extra";
import { FileHandle, readFile } from "fs/promises";
import type { WriteStream } from "fs";
import { constants } from "fs";
import { open, mkdir, unlink } from "fs/promises";
import path from "path";
import type * as FetchModule from "node-fetch";
import { promisify } from "util";
import { pipeline as _pipeline, Transform, Writable } from "stream";
import type { SingleBar } from "cli-progress";
import { MultiBar } from "cli-progress";
import { extract } from "tar-stream";
import gunzip from "gunzip-maybe";
import { isErrnoException, setTimeoutFor } from "../src/common/utils";
import AbortController from "abort-controller";
import fetch from "node-fetch"
import z from "zod";
import arg from "arg";
type Response = FetchModule.Response;
type RequestInfo = FetchModule.RequestInfo;
type RequestInit = FetchModule.RequestInit;
const options = arg({
"--package": String,
"--base-dir": String,
});
const pathToPackage = options["--package"];
const pathToBaseDir = options["--base-dir"];
if (typeof pathToPackage !== "string") {
throw new Error("--package is required");
}
if (typeof pathToBaseDir !== "string") {
throw new Error("--base-dir is required");
}
function setTimeoutFor(controller: AbortController, timeout: number): void {
const handle = setTimeout(() => controller.abort(), timeout);
controller.signal.addEventListener("abort", () => clearTimeout(handle));
}
const pipeline = promisify(_pipeline);
@ -41,10 +59,6 @@ interface BinaryDownloaderArgs {
readonly baseDir: string;
}
interface BinaryDownloaderDependencies {
fetch: (url: RequestInfo, init?: RequestInit) => Promise<Response>;
}
abstract class BinaryDownloader {
protected abstract readonly url: string;
protected readonly bar: SingleBar;
@ -54,7 +68,7 @@ abstract class BinaryDownloader {
return [file];
}
constructor(protected readonly dependencies: BinaryDownloaderDependencies, public readonly args: BinaryDownloaderArgs, multiBar: MultiBar) {
constructor(public readonly args: BinaryDownloaderArgs, multiBar: MultiBar) {
this.bar = multiBar.create(1, 0, args);
this.target = path.join(args.baseDir, args.platform, args.fileArch, args.binaryName);
}
@ -68,7 +82,7 @@ abstract class BinaryDownloader {
setTimeoutFor(controller, 15 * 60 * 1000);
const stream = await this.dependencies.fetch(this.url, {
const stream = await fetch(this.url, {
signal: controller.signal,
});
const total = Number(stream.headers.get("content-length"));
@ -81,7 +95,10 @@ abstract class BinaryDownloader {
bar.setTotal(total);
await ensureDir(path.dirname(this.target), 0o755);
await mkdir(path.dirname(this.target), {
mode: 0o755,
recursive: true,
});
try {
/**
@ -116,7 +133,7 @@ abstract class BinaryDownloader {
} catch (error) {
await fileHandle?.close();
if (isErrnoException(error) && error.code === "EEXIST") {
if ((error as any)?.code === "EEXIST") {
bar.increment(total); // mark as finished
controller.abort(); // stop trying to download
} else {
@ -130,10 +147,10 @@ abstract class BinaryDownloader {
class LensK8sProxyDownloader extends BinaryDownloader {
protected readonly url: string;
constructor(deps: BinaryDownloaderDependencies, args: Omit<BinaryDownloaderArgs, "binaryName">, bar: MultiBar) {
constructor(args: Omit<BinaryDownloaderArgs, "binaryName">, bar: MultiBar) {
const binaryName = getBinaryName("lens-k8s-proxy", { forPlatform: args.platform });
super(deps, { ...args, binaryName }, bar);
super({ ...args, binaryName }, bar);
this.url = `https://github.com/lensapp/lens-k8s-proxy/releases/download/v${args.version}/lens-k8s-proxy-${args.platform}-${args.downloadArch}`;
}
}
@ -141,10 +158,10 @@ class LensK8sProxyDownloader extends BinaryDownloader {
class KubectlDownloader extends BinaryDownloader {
protected readonly url: string;
constructor(deps: BinaryDownloaderDependencies, args: Omit<BinaryDownloaderArgs, "binaryName">, bar: MultiBar) {
constructor(args: Omit<BinaryDownloaderArgs, "binaryName">, bar: MultiBar) {
const binaryName = getBinaryName("kubectl", { forPlatform: args.platform });
super(deps, { ...args, binaryName }, bar);
super({ ...args, binaryName }, bar);
this.url = `https://storage.googleapis.com/kubernetes-release/release/v${args.version}/bin/${args.platform}/${args.downloadArch}/${binaryName}`;
}
}
@ -152,10 +169,10 @@ class KubectlDownloader extends BinaryDownloader {
class HelmDownloader extends BinaryDownloader {
protected readonly url: string;
constructor(deps: BinaryDownloaderDependencies, args: Omit<BinaryDownloaderArgs, "binaryName">, bar: MultiBar) {
constructor(args: Omit<BinaryDownloaderArgs, "binaryName">, bar: MultiBar) {
const binaryName = getBinaryName("helm", { forPlatform: args.platform });
super(deps, { ...args, binaryName }, bar);
super({ ...args, binaryName }, bar);
this.url = `https://get.helm.sh/helm-v${args.version}-${args.platform}-${args.downloadArch}.tar.gz`;
}
@ -182,99 +199,100 @@ class HelmDownloader extends BinaryDownloader {
type SupportedPlatform = "darwin" | "linux" | "windows";
const importFetchModule = new Function('return import("node-fetch")') as () => Promise<typeof FetchModule>;
const PackageInfo = z.object({
config: z.object({
k8sProxyVersion: z.string().min(1),
bundledKubectlVersion: z.string().min(1),
bundledHelmVersion: z.string().min(1),
})
})
async function main() {
const deps: BinaryDownloaderDependencies = {
fetch: (await importFetchModule()).default,
};
const normalizedPlatform = (() => {
switch (process.platform) {
case "darwin":
return "darwin";
case "linux":
return "linux";
case "win32":
return "windows";
default:
throw new Error(`platform=${process.platform} is unsupported`);
}
})();
const multiBar = new MultiBar({
align: "left",
clearOnComplete: false,
hideCursor: true,
autopadding: true,
noTTYOutput: true,
format: "[{bar}] {percentage}% | {downloadArch} {binaryName}",
});
const baseDir = path.join(process.cwd(), "binaries", "client");
const downloaders: BinaryDownloader[] = [
new LensK8sProxyDownloader(deps, {
const packageInfoRaw = await readFile(pathToPackage, "utf-8");
const packageInfo = PackageInfo.parse(JSON.parse(packageInfoRaw));
const normalizedPlatform = (() => {
switch (process.platform) {
case "darwin":
return "darwin";
case "linux":
return "linux";
case "win32":
return "windows";
default:
throw new Error(`platform=${process.platform} is unsupported`);
}
})();
const multiBar = new MultiBar({
align: "left",
clearOnComplete: false,
hideCursor: true,
autopadding: true,
noTTYOutput: true,
format: "[{bar}] {percentage}% | {downloadArch} {binaryName}",
});
const downloaders: BinaryDownloader[] = [
new LensK8sProxyDownloader({
version: packageInfo.config.k8sProxyVersion,
platform: normalizedPlatform,
downloadArch: "amd64",
fileArch: "x64",
baseDir: pathToBaseDir,
}, multiBar),
new KubectlDownloader({
version: packageInfo.config.bundledKubectlVersion,
platform: normalizedPlatform,
downloadArch: "amd64",
fileArch: "x64",
baseDir: pathToBaseDir,
}, multiBar),
new HelmDownloader({
version: packageInfo.config.bundledHelmVersion,
platform: normalizedPlatform,
downloadArch: "amd64",
fileArch: "x64",
baseDir: pathToBaseDir,
}, multiBar),
];
if (normalizedPlatform !== "windows") {
downloaders.push(
new LensK8sProxyDownloader({
version: packageInfo.config.k8sProxyVersion,
platform: normalizedPlatform,
downloadArch: "amd64",
fileArch: "x64",
baseDir,
downloadArch: "arm64",
fileArch: "arm64",
baseDir: pathToBaseDir,
}, multiBar),
new KubectlDownloader(deps, {
new KubectlDownloader({
version: packageInfo.config.bundledKubectlVersion,
platform: normalizedPlatform,
downloadArch: "amd64",
fileArch: "x64",
baseDir,
downloadArch: "arm64",
fileArch: "arm64",
baseDir: pathToBaseDir,
}, multiBar),
new HelmDownloader(deps, {
new HelmDownloader({
version: packageInfo.config.bundledHelmVersion,
platform: normalizedPlatform,
downloadArch: "amd64",
fileArch: "x64",
baseDir,
downloadArch: "arm64",
fileArch: "arm64",
baseDir: pathToBaseDir,
}, multiBar),
];
if (normalizedPlatform !== "windows") {
downloaders.push(
new LensK8sProxyDownloader(deps, {
version: packageInfo.config.k8sProxyVersion,
platform: normalizedPlatform,
downloadArch: "arm64",
fileArch: "arm64",
baseDir,
}, multiBar),
new KubectlDownloader(deps, {
version: packageInfo.config.bundledKubectlVersion,
platform: normalizedPlatform,
downloadArch: "arm64",
fileArch: "arm64",
baseDir,
}, multiBar),
new HelmDownloader(deps, {
version: packageInfo.config.bundledHelmVersion,
platform: normalizedPlatform,
downloadArch: "arm64",
fileArch: "arm64",
baseDir,
}, multiBar),
);
}
const settledResults = await Promise.allSettled(downloaders.map(downloader => (
downloader.ensureBinary()
.catch(error => {
throw new Error(`Failed to download ${downloader.args.binaryName} for ${downloader.args.platform}/${downloader.args.downloadArch}: ${error}`);
})
)));
multiBar.stop();
const errorResult = settledResults.find(res => res.status === "rejected") as PromiseRejectedResult | undefined;
if (errorResult) {
console.error("234", String(errorResult.reason));
process.exit(1);
}
process.exit(0);
);
}
main().catch(error => console.error("from main", error));
const settledResults = await Promise.allSettled(downloaders.map(downloader => (
downloader.ensureBinary()
.catch(error => {
throw new Error(`Failed to download ${downloader.args.binaryName} for ${downloader.args.platform}/${downloader.args.downloadArch}: ${error}`);
})
)));
multiBar.stop();
const errorResult = settledResults.find(res => res.status === "rejected") as PromiseRejectedResult | undefined;
if (errorResult) {
console.error("234", String(errorResult.reason));
process.exit(1);
}
process.exit(0);

View File

@ -0,0 +1,19 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"composite": true,
"outDir": "dist/",
"paths": {
"*": [
"node_modules/*",
"types/*"
]
},
},
"include": [
"src/**/*",
],
"exclude": [
"node_modules",
]
}

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
"name": "@k8slens/extensions",
"productName": "OpenLens extensions",
"description": "OpenLens - Open Source Kubernetes IDE: extensions",
"version": "6.4.0-alpha.2",
"version": "6.4.0-beta.8",
"copyright": "© 2022 OpenLens Authors",
"license": "MIT",
"main": "dist/src/extension-api.js",
@ -15,14 +15,18 @@
"author": {
"name": "OpenLens Authors"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"scripts": {
"build": "yarn run webpack --config webpack/extensions.ts",
"build-docs": "yarn run typedoc",
"build:docs": "yarn run typedoc",
"clean": "rm -rf dist/",
"prepare:dev": "yarn run build"
},
"dependencies": {
"@k8slens/open-lens": "^6.4.0-alpha.2"
"@k8slens/core": "^6.4.0-beta.8"
},
"devDependencies": {
"@types/node": "^16.18.6",

View File

@ -3,16 +3,8 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { extensionApi as main } from "@k8slens/open-lens/main";
import { extensionApi as renderer } from "@k8slens/open-lens/renderer";
import { extensionApi as common } from "@k8slens/open-lens/common";
import { extensionApi as Main } from "@k8slens/core/main";
import { extensionApi as Renderer } from "@k8slens/core/renderer";
import { extensionApi as Common } from "@k8slens/core/common";
const Main = { ... main } as typeof main;
const Renderer = { ...renderer } as typeof renderer;
const Common = { ... common } as typeof common;
export {
Main,
Renderer,
Common,
};
export { Main, Renderer, Common };

View File

@ -4,11 +4,9 @@
"out": "../../docs/extensions/api",
"excludePrivate": true,
"entryPointStrategy": "expand",
"excludeExternals": true,
"entryPoints": [
"src/extension-api.ts",
"../core/src/common/library.ts",
"../core/src/main/library.ts",
"../core/src/renderer/library.ts"
],
"hideBreadcrumbs": true,
"disableSources": true,

View File

@ -35,9 +35,9 @@ export default function generateExtensionTypes(): webpack.Configuration {
],
stats: "errors-warnings",
externals: [
"@k8slens/open-lens/common",
"@k8slens/open-lens/main",
"@k8slens/open-lens/renderer",
"@k8slens/core/common",
"@k8slens/core/main",
"@k8slens/core/renderer",
],
module: {
rules: [

2
packages/node-fetch/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
dist/
node_modules/

View File

@ -0,0 +1,3 @@
# Description
This is a CommonJS webpack transpilation of the `node-fetch` package for use within `electron-renderer`.

View File

@ -0,0 +1,31 @@
{
"name": "@k8slens/node-fetch",
"version": "6.4.0-beta.8",
"description": "Node fetch for Lens",
"license": "MIT",
"private": false,
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"clean": "rm -rf dist/",
"build": "webpack --config webpack.ts",
"lint": "exit 0",
"prepare": "npm run build",
"prepare:dev": "yarn run build",
"prepare:test": "yarn run build"
},
"dependencies": {
"node-fetch": "^3.3.0"
},
"devDependencies": {
"ts-loader": "^9.4.2",
"ts-node": "^10.9.1",
"typescript": "^4.9.4",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
}
}

View File

@ -0,0 +1,4 @@
import fetch from "node-fetch";
export * from "node-fetch";
export default fetch;

View File

@ -0,0 +1,18 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist/",
"paths": {
"*": [
"node_modules/*",
"types/*"
]
},
},
"include": [
"src/**/*",
],
"exclude": [
"node_modules",
]
}

View File

@ -5,12 +5,11 @@
import path from "path";
export default {
entry: "./node_modules/node-fetch/src/index.js",
entry: "./src/index.ts",
output: {
path: path.resolve(__dirname, "..", "build", "webpack"),
filename: "node-fetch.bundle.js",
path: path.resolve(__dirname, "dist"),
filename: "index.js",
library: {
name: "NodeFetch",
type: "commonjs",
},
clean: true,
@ -25,7 +24,22 @@ export default {
externalsPresets: {
node: true,
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
loader: "ts-loader",
options: {
compilerOptions: {
declaration: true,
sourceMap: false,
outDir: path.resolve("./dist/"),
},
},
}
]
},
resolve: {
extensions: [".js"],
extensions: [".ts"],
},
};

File diff suppressed because it is too large Load Diff

View File

@ -1,280 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import packageInfo from "../package.json";
import type { FileHandle } from "fs/promises";
import { open } from "fs/promises";
import type { WriteStream } from "fs-extra";
import { constants, ensureDir, unlink } from "fs-extra";
import path from "path";
import type * as FetchModule from "node-fetch";
import { promisify } from "util";
import { pipeline as _pipeline, Transform, Writable } from "stream";
import type { SingleBar } from "cli-progress";
import { MultiBar } from "cli-progress";
import { extract } from "tar-stream";
import gunzip from "gunzip-maybe";
import { isErrnoException, setTimeoutFor } from "../../core/src/common/utils";
import AbortController from "abort-controller";
type Response = FetchModule.Response;
type RequestInfo = FetchModule.RequestInfo;
type RequestInit = FetchModule.RequestInit;
const pipeline = promisify(_pipeline);
const getBinaryName = (binaryName: string, { forPlatform }: { forPlatform : string }) => {
if (forPlatform === "windows") {
return `${binaryName}.exe`;
}
return binaryName;
};
interface BinaryDownloaderArgs {
readonly version: string;
readonly platform: SupportedPlatform;
readonly downloadArch: string;
readonly fileArch: string;
readonly binaryName: string;
readonly baseDir: string;
}
interface BinaryDownloaderDependencies {
fetch: (url: RequestInfo, init?: RequestInit) => Promise<Response>;
}
abstract class BinaryDownloader {
protected abstract readonly url: string;
protected readonly bar: SingleBar;
protected readonly target: string;
protected getTransformStreams(file: Writable): (NodeJS.ReadWriteStream | NodeJS.WritableStream)[] {
return [file];
}
constructor(protected readonly dependencies: BinaryDownloaderDependencies, public readonly args: BinaryDownloaderArgs, multiBar: MultiBar) {
this.bar = multiBar.create(1, 0, args);
this.target = path.join(args.baseDir, args.platform, args.fileArch, args.binaryName);
}
async ensureBinary(): Promise<void> {
if (process.env.LENS_SKIP_DOWNLOAD_BINARIES === "true") {
return;
}
const controller = new AbortController();
setTimeoutFor(controller, 15 * 60 * 1000);
const stream = await this.dependencies.fetch(this.url, {
signal: controller.signal,
});
const total = Number(stream.headers.get("content-length"));
const bar = this.bar;
let fileHandle: FileHandle | undefined = undefined;
if (isNaN(total)) {
throw new Error("no content-length header was present");
}
bar.setTotal(total);
await ensureDir(path.dirname(this.target), 0o755);
try {
/**
* This is necessary because for some reason `createWriteStream({ flags: "wx" })`
* was throwing someplace else and not here
*/
const handle = fileHandle = await open(this.target, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL);
if (!stream.body) {
throw new Error("no body on stream");
}
await pipeline(
stream.body,
new Transform({
transform(chunk, encoding, callback) {
bar.increment(chunk.length);
this.push(chunk);
callback();
},
}),
...this.getTransformStreams(new Writable({
write(chunk, encoding, cb) {
handle.write(chunk)
.then(() => cb())
.catch(cb);
},
})),
);
await fileHandle.chmod(0o755);
await fileHandle.close();
} catch (error) {
await fileHandle?.close();
if (isErrnoException(error) && error.code === "EEXIST") {
bar.increment(total); // mark as finished
controller.abort(); // stop trying to download
} else {
await unlink(this.target);
throw error;
}
}
}
}
class LensK8sProxyDownloader extends BinaryDownloader {
protected readonly url: string;
constructor(deps: BinaryDownloaderDependencies, args: Omit<BinaryDownloaderArgs, "binaryName">, bar: MultiBar) {
const binaryName = getBinaryName("lens-k8s-proxy", { forPlatform: args.platform });
super(deps, { ...args, binaryName }, bar);
this.url = `https://github.com/lensapp/lens-k8s-proxy/releases/download/v${args.version}/lens-k8s-proxy-${args.platform}-${args.downloadArch}`;
}
}
class KubectlDownloader extends BinaryDownloader {
protected readonly url: string;
constructor(deps: BinaryDownloaderDependencies, args: Omit<BinaryDownloaderArgs, "binaryName">, bar: MultiBar) {
const binaryName = getBinaryName("kubectl", { forPlatform: args.platform });
super(deps, { ...args, binaryName }, bar);
this.url = `https://storage.googleapis.com/kubernetes-release/release/v${args.version}/bin/${args.platform}/${args.downloadArch}/${binaryName}`;
}
}
class HelmDownloader extends BinaryDownloader {
protected readonly url: string;
constructor(deps: BinaryDownloaderDependencies, args: Omit<BinaryDownloaderArgs, "binaryName">, bar: MultiBar) {
const binaryName = getBinaryName("helm", { forPlatform: args.platform });
super(deps, { ...args, binaryName }, bar);
this.url = `https://get.helm.sh/helm-v${args.version}-${args.platform}-${args.downloadArch}.tar.gz`;
}
protected getTransformStreams(file: WriteStream) {
const extracting = extract({
allowUnknownFormat: false,
});
extracting.on("entry", (headers, stream, next) => {
if (headers.name.endsWith(this.args.binaryName)) {
stream
.pipe(file)
.once("finish", () => next())
.once("error", next);
} else {
stream.resume();
next();
}
});
return [gunzip(3), extracting];
}
}
type SupportedPlatform = "darwin" | "linux" | "windows";
const importFetchModule = new Function('return import("node-fetch")') as () => Promise<typeof FetchModule>;
async function main() {
const deps: BinaryDownloaderDependencies = {
fetch: (await importFetchModule()).default,
};
const normalizedPlatform = (() => {
switch (process.platform) {
case "darwin":
return "darwin";
case "linux":
return "linux";
case "win32":
return "windows";
default:
throw new Error(`platform=${process.platform} is unsupported`);
}
})();
const multiBar = new MultiBar({
align: "left",
clearOnComplete: false,
hideCursor: true,
autopadding: true,
noTTYOutput: true,
format: "[{bar}] {percentage}% | {downloadArch} {binaryName}",
});
const baseDir = path.join(process.cwd(), "binaries", "client");
const downloaders: BinaryDownloader[] = [
new LensK8sProxyDownloader(deps, {
version: packageInfo.config.k8sProxyVersion,
platform: normalizedPlatform,
downloadArch: "amd64",
fileArch: "x64",
baseDir,
}, multiBar),
new KubectlDownloader(deps, {
version: packageInfo.config.bundledKubectlVersion,
platform: normalizedPlatform,
downloadArch: "amd64",
fileArch: "x64",
baseDir,
}, multiBar),
new HelmDownloader(deps, {
version: packageInfo.config.bundledHelmVersion,
platform: normalizedPlatform,
downloadArch: "amd64",
fileArch: "x64",
baseDir,
}, multiBar),
];
if (normalizedPlatform !== "windows") {
downloaders.push(
new LensK8sProxyDownloader(deps, {
version: packageInfo.config.k8sProxyVersion,
platform: normalizedPlatform,
downloadArch: "arm64",
fileArch: "arm64",
baseDir,
}, multiBar),
new KubectlDownloader(deps, {
version: packageInfo.config.bundledKubectlVersion,
platform: normalizedPlatform,
downloadArch: "arm64",
fileArch: "arm64",
baseDir,
}, multiBar),
new HelmDownloader(deps, {
version: packageInfo.config.bundledHelmVersion,
platform: normalizedPlatform,
downloadArch: "arm64",
fileArch: "arm64",
baseDir,
}, multiBar),
);
}
const settledResults = await Promise.allSettled(downloaders.map(downloader => (
downloader.ensureBinary()
.catch(error => {
throw new Error(`Failed to download ${downloader.args.binaryName} for ${downloader.args.platform}/${downloader.args.downloadArch}: ${error}`);
})
)));
multiBar.stop();
const errorResult = settledResults.find(res => res.status === "rejected") as PromiseRejectedResult | undefined;
if (errorResult) {
console.error("234", String(errorResult.reason));
process.exit(1);
}
process.exit(0);
}
main().catch(error => console.error("from main", error));

View File

@ -4,7 +4,7 @@
"productName": "OpenLens",
"description": "OpenLens - Open Source IDE for Kubernetes",
"homepage": "https://github.com/lensapp/lens",
"version": "6.4.0-alpha.2",
"version": "6.4.0-beta.8",
"repository": {
"type": "git",
"url": "git+https://github.com/lensapp/lens.git"
@ -35,7 +35,7 @@
"dev:renderer": "env NODE_ENV=development ts-node ./webpack/dev-server.ts",
"test:integration": "jest -xyz --runInBand --detectOpenHandles --forceExit --modulePaths=[\"<rootDir>/integration/\"];",
"build:tray-icons": "ts-node build/generate-tray-icons.ts",
"download:binaries": "ts-node build/download_binaries.ts"
"download:binaries": "npm exec -- @k8slens/download-binaries --package $INIT_CWD/package.json --base-dir $INIT_CWD/binaries/client"
},
"config": {
"k8sProxyVersion": "0.3.0",
@ -97,8 +97,8 @@
"generateUpdatesFilesForAllChannels": true,
"files": [
"static/**/*",
"!node_modules/@k8slens/open-lens/node_modules/**/*",
"!node_modules/@k8slens/open-lens/src"
"!node_modules/@k8slens/core/node_modules/**/*",
"!node_modules/@k8slens/core/src"
],
"afterSign": "build/notarize.js",
"extraResources": [
@ -192,7 +192,8 @@
}
},
"dependencies": {
"@k8slens/open-lens": "^6.4.0-alpha.2",
"@k8slens/core": "^6.4.0-beta.8",
"@k8slens/download-binaries": "^6.4.0-beta.8",
"@ogre-tools/fp": "^12.0.1",
"@ogre-tools/injectable": "^12.0.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1",
@ -201,18 +202,16 @@
"mobx": "^6.7.0"
},
"devDependencies": {
"@k8slens/node-fetch": "^6.4.0-beta.8",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@swc/core": "^1.3.26",
"@swc/core": "^1.3.28",
"@swc/jest": "^0.2.24",
"@types/byline": "^4.2.33",
"@types/chart.js": "^2.9.36",
"@types/cli-progress": "^3.11.0",
"@types/color": "^3.0.3",
"@types/crypto-js": "^3.1.47",
"@types/gunzip-maybe": "^1.4.0",
"@types/lodash": "^4.14.191",
"@types/node": "^16.18.6",
"@types/node-fetch": "^2.6.2",
"@types/proper-lockfile": "^4.1.2",
"@types/react-dom": "^17.0.16",
"@types/react-router-dom": "^5.3.3",
@ -220,7 +219,6 @@
"@types/react-window": "^1.8.5",
"@types/request-promise-native": "^1.0.18",
"@types/tar": "^6.1.3",
"@types/tar-stream": "^2.2.2",
"@types/tcp-port-used": "^1.0.1",
"@types/url-parse": "^1.4.8",
"@types/uuid": "^8.3.4",
@ -231,15 +229,13 @@
"abort-controller": "^3.0.0",
"autoprefixer": "^10.4.13",
"circular-dependency-plugin": "^5.2.2",
"cli-progress": "^3.11.2",
"concurrently": "^7.6.0",
"css-loader": "^6.7.2",
"electron": "^19.1.9",
"electron-builder": "^23.6.0",
"electron-notarize": "^0.3.0",
"esbuild-loader": "^2.20.0",
"fork-ts-checker-webpack-plugin": "^7.2.14",
"gunzip-maybe": "^1.4.2",
"fork-ts-checker-webpack-plugin": "^7.3.0",
"html-webpack-plugin": "^5.5.0",
"jest": "^28.1.3",
"jest-environment-jsdom": "^28.1.3",
@ -250,7 +246,7 @@
"monaco-editor-webpack-plugin": "^5.0.0",
"node-loader": "^2.0.0",
"nodemon": "^2.0.20",
"playwright": "^1.29.2",
"playwright": "^1.30.0",
"react-refresh": "^0.14.0",
"react-refresh-typescript": "^2.0.7",
"react-select": "^5.7.0",

View File

@ -1,6 +1,6 @@
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken, ApplicationInformation } from "@k8slens/open-lens/common";
import { applicationInformationToken, ApplicationInformation } from "@k8slens/core/common";
import packageJson from "../../package.json";
const applicationInformationInjectable = getInjectable({

View File

@ -1,7 +1,7 @@
import { createContainer } from "@ogre-tools/injectable";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
import { runInAction } from "mobx";
import { createApp, extensionApi } from "@k8slens/open-lens/main";
import { createApp, extensionApi } from "@k8slens/core/main";
const di = createContainer("main");
const app = createApp({

View File

@ -1,7 +1,7 @@
import "@k8slens/open-lens/styles";
import "@k8slens/core/styles";
import { createContainer } from "@ogre-tools/injectable";
import { runInAction } from "mobx";
import { createApp, extensionApi } from "@k8slens/open-lens/renderer";
import { createApp, extensionApi } from "@k8slens/core/renderer";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
const di = createContainer("renderer");

View File

@ -50,7 +50,6 @@
],
},
externals: [
"node-fetch",
"npm",
"win-ca"
],

View File

@ -11,9 +11,9 @@ export const mainDir = path.join(process.cwd(), "src", "main");
export const buildDir = path.join(process.cwd(), "static", "build");
export const assetsFolderName = "assets";
export const rendererDir = path.join(process.cwd(), "src", "renderer");
export const htmlTemplate = path.resolve(__dirname, "..", "node_modules", "@k8slens", "open-lens", "src/renderer", "template.html");
export const htmlTemplate = path.resolve(__dirname, "..", "node_modules", "@k8slens", "core", "src/renderer", "template.html");
export const publicPath = "/build/";
export const sassCommonVars = path.resolve(__dirname, "..", "node_modules", "@k8slens", "open-lens", "src", "renderer", "components/vars.scss");
export const sassCommonVars = path.resolve(__dirname, "..", "node_modules", "@k8slens", "core", "src", "renderer", "components/vars.scss");
export const webpackDevServerPort = Number(process.env.WEBPACK_DEV_SERVER_PORT) || 9191;
assert(Number.isInteger(webpackDevServerPort), "WEBPACK_DEV_SERVER_PORT environment variable must only be an integer");

View File

@ -865,71 +865,71 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
"@swc/core-darwin-arm64@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.26.tgz#43355315f0668a6a5366208f09678349bc0f44ee"
integrity sha512-FWWflBfKRYrUJtko2xiedC5XCa31O75IZZqnTWuLpe9g3C5tnUuF3M8LSXZS/dn6wprome1MhtG9GMPkSYkhkg==
"@swc/core-darwin-arm64@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.28.tgz#3ab15dd6f0ede5b3c7d6ed557a26c0fad34ee5c9"
integrity sha512-f1ph5DDIOX6bvjhlOuWz8ZDiTghhq144Sy9gaRi+DjK3gdnftc4p5AyZHA4Xb03MZ+fd0mj8q6/znco5aBMi1A==
"@swc/core-darwin-x64@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.26.tgz#462fc2e1377437b7c7bbdf5988f51adfeea3efa9"
integrity sha512-0uQeebAtsewqJ2b35aPZstGrylwd6oJjUyAJOfVJNbremFSJ5JzytB3NoDCIw7CT5UQrSRpvD3mU95gfdQjDGA==
"@swc/core-darwin-x64@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.28.tgz#e0eaa0eb763bc7def581df93b1a5df1249eb5528"
integrity sha512-5dB5Z4Ry45UTXXAxhwagCYfh57njffkdIJkjid1f+Qt4i7cOznOaIiD4wobGD7xHCATEcs8F23yWkAmvrbacew==
"@swc/core-linux-arm-gnueabihf@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.26.tgz#fecd9c2e7d9b69c849907a83a5101a98c047d986"
integrity sha512-06T+LbVFlyciQtwrUB5/a16A1ju1jFoYvd/hq9TWhf7GrtL43U7oJIgqMOPHx2j0+Ps2R3S6R/UUN5YXu618zA==
"@swc/core-linux-arm-gnueabihf@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.28.tgz#f7038e60bddebc6b0c0aa444c50157fe4908fb58"
integrity sha512-VmtAQAENJ5SHBXTKxXNlnnM34xGOtJpHYva83zeZM/2epdoz1BJ6Ny3gTBXDftaWgAj2SRwVIjMR3/c71aJysQ==
"@swc/core-linux-arm64-gnu@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.26.tgz#82a8462212263f4e4f6691473d4c2839b73c2084"
integrity sha512-2NT/0xALPfK+U01qIlHxjkGdIj6F0txhu1U2v6B0YP2+k0whL2gCgYeg9QUvkYEXSD5r1Yx+vcb2R/vaSCSClg==
"@swc/core-linux-arm64-gnu@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.28.tgz#6e3013176c4cc5dd006c848911e3bccaf1fa77dd"
integrity sha512-KIJ1SHGbusM6W2rxue1f+IN/iuzmspgMY9qP/qW5Z43Mm9mrHdzDmhsMoEH1y2gPUsu/ZZnkXlODJ0M0454JNQ==
"@swc/core-linux-arm64-musl@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.26.tgz#050b7c1aa81d6f34769eb556c3a94c61a9b69aaa"
integrity sha512-64KrTay9hC0mTvZ1AmEFmNEwV5QDjw9U7PJU5riotSc28I+Q/ZoM0qcSFW9JRRa6F2Tr+IfMtyv8+eB2//BQ5g==
"@swc/core-linux-arm64-musl@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.28.tgz#01896d81f967104fb851534962dd344252d85025"
integrity sha512-Zz2DZj8ncSvVEAsol8gtoXrVLP8e+IYSx6o8txYVR0p0pviJBzeuYGaLe5sbQdQnVVS2M5N90LX28P6/mQb6sQ==
"@swc/core-linux-x64-gnu@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.26.tgz#e306778c2c1838350f588c8ae800e74434dc2b9a"
integrity sha512-Te8G13l3dcRM1Mf3J4JzGUngzNXLKnMYlUmBOYN/ORsx7e+VNelR3zsTLHC0+0jGqELDgqvMyzDfk+dux/C/bQ==
"@swc/core-linux-x64-gnu@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.28.tgz#03d9b0171267ccc5d0efd2a939150f5d1da550ae"
integrity sha512-Za3uowhcP74qSCNqjZLBx3nAmjIFYNbB0nGBKwkLBopbMcpO0BjvnsdzmoWqv2Uq41vaeVk/o9vATQMojfHHQg==
"@swc/core-linux-x64-musl@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.26.tgz#531d9ec7c37f56df5c6cc121db5dd6faff5e2c38"
integrity sha512-nqQWuSM6OTKepUiQ9+rXgERq/JiO72RBOpXKO2afYppsL96sngjIRewV74v5f6IAfyzw+k+AhC5pgRA4Xu/Jkg==
"@swc/core-linux-x64-musl@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.28.tgz#6badfc87d94b7891c11aa71496498d2ff29535db"
integrity sha512-i3BAkmrf19VXybbjuS9Jnlnx5Ie4vukLMCQRfXCQqIqaiSw3QzubjolYo07sGtzoVI3nBscDt3i8T+oxTPOMkw==
"@swc/core-win32-arm64-msvc@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.26.tgz#9c7f245903694484bd00c4da5142f24070094d0f"
integrity sha512-xx34mx+9IBV1sun7sxoNFiqNom9wiOuvsQFJUyQptCnZHgYwOr9OI204LBF95dCcBCZsTm2hT1wBnySJOeimYw==
"@swc/core-win32-arm64-msvc@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.28.tgz#2441d2cdbc313618332de014be0c6c3573931b62"
integrity sha512-DdNxKP/P0/OFqX1dtl9Ubrd567QPMSeJvp9iDtMdgCBWN2N6HXvyMj623WIA0y9FIcA7wexz0Hh3gS+G9Jof+Q==
"@swc/core-win32-ia32-msvc@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.26.tgz#56d83cc216218d78cc578f01499777cdfc0a4eeb"
integrity sha512-48LZ/HKNuU9zl8c7qG6IQKb5rBCwmJgysGOmEGzTRBYxAf/x6Scmt0aqxCoV4J02HOs2WduCBDnhUKsSQ2kcXQ==
"@swc/core-win32-ia32-msvc@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.28.tgz#82319fcff87289e3e9439dd76524a7bdfe58f5fa"
integrity sha512-/jZWBIgaNkKTlKiZ7DXmMJzW0n1ychDKS1bYRuNLrtTRthMP5M3LRZXITz0AcvPl0mIA0IXeMQbE4ZMUc7LAFg==
"@swc/core-win32-x64-msvc@1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.26.tgz#bb65bc0fff712c8ca3702d9c0adc59894ca54bae"
integrity sha512-UPe7S+MezD/S6cKBIc50TduGzmw6PBz1Ms5p+5wDLOKYNS/LSEM4iRmLwvePzP5X8mOyesXrsbwxLy8KHP65Yw==
"@swc/core-win32-x64-msvc@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.28.tgz#a2067da2f3f4f95ef1b05eb86941d0609a66e9c6"
integrity sha512-HKhE0LznEwTP/qi6EVclmJzfNdykzuK6sjYMTjcDqNJOuuRNMu+IJzPzCPuakgljymWGFmddnuuubd9Y+kl3eg==
"@swc/core@^1.3.26":
version "1.3.26"
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.26.tgz#6f7fe6ad54eac7ecffbdfa75d5c4300e2f96b8f6"
integrity sha512-U7vEsaLn3IGg0XCRLJX/GTkK9WIfFHUX5USdrp1L2QD29sWPe25HqNndXmUR9KytzKmpDMNoUuHyiuhpVrnNeQ==
"@swc/core@^1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.28.tgz#e0fc1fd15b2e7e01d0f16d55eb60b74e65fb1025"
integrity sha512-yzc61HbAIjHeOYTUW/IgXAywlSviMFymnUiLY7dNUELGHjMVxSp0XnIlPQN4v5UekYbwLEV8+KChaoQRACiQCw==
optionalDependencies:
"@swc/core-darwin-arm64" "1.3.26"
"@swc/core-darwin-x64" "1.3.26"
"@swc/core-linux-arm-gnueabihf" "1.3.26"
"@swc/core-linux-arm64-gnu" "1.3.26"
"@swc/core-linux-arm64-musl" "1.3.26"
"@swc/core-linux-x64-gnu" "1.3.26"
"@swc/core-linux-x64-musl" "1.3.26"
"@swc/core-win32-arm64-msvc" "1.3.26"
"@swc/core-win32-ia32-msvc" "1.3.26"
"@swc/core-win32-x64-msvc" "1.3.26"
"@swc/core-darwin-arm64" "1.3.28"
"@swc/core-darwin-x64" "1.3.28"
"@swc/core-linux-arm-gnueabihf" "1.3.28"
"@swc/core-linux-arm64-gnu" "1.3.28"
"@swc/core-linux-arm64-musl" "1.3.28"
"@swc/core-linux-x64-gnu" "1.3.28"
"@swc/core-linux-x64-musl" "1.3.28"
"@swc/core-win32-arm64-msvc" "1.3.28"
"@swc/core-win32-ia32-msvc" "1.3.28"
"@swc/core-win32-x64-msvc" "1.3.28"
"@swc/jest@^0.2.24":
version "0.2.24"
@ -1038,13 +1038,6 @@
dependencies:
moment "^2.10.2"
"@types/cli-progress@^3.11.0":
version "3.11.0"
resolved "https://registry.yarnpkg.com/@types/cli-progress/-/cli-progress-3.11.0.tgz#ec79df99b26757c3d1c7170af8422e0fc95eef7e"
integrity sha512-XhXhBv1R/q2ahF3BM7qT5HLzJNlIL0wbcGyZVjqOTqAybAnsLisd7gy1UCyIqpL+5Iv6XhlSyzjLCnI2sIdbCg==
dependencies:
"@types/node" "*"
"@types/color-convert@*":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-2.0.0.tgz#8f5ee6b9e863dcbee5703f5a517ffb13d3ea4e22"
@ -1158,13 +1151,6 @@
dependencies:
"@types/node" "*"
"@types/gunzip-maybe@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@types/gunzip-maybe/-/gunzip-maybe-1.4.0.tgz#9410fd15ff68eca8907b7b9198e63e2a7c14d511"
integrity sha512-dFP9GrYAR9KhsjTkWJ8q8Gsfql75YIKcg9DuQOj/IrlPzR7W+1zX+cclw1McV82UXAQ+Lpufvgk3e9bC8+HzgA==
dependencies:
"@types/node" "*"
"@types/history@^4.7.11":
version "4.7.11"
resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64"
@ -1235,14 +1221,6 @@
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
"@types/node-fetch@^2.6.2":
version "2.6.2"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da"
integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==
dependencies:
"@types/node" "*"
form-data "^3.0.0"
"@types/node@*":
version "18.11.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
@ -1420,13 +1398,6 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
"@types/tar-stream@^2.2.2":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/tar-stream/-/tar-stream-2.2.2.tgz#be9d0be9404166e4b114151f93e8442e6ab6fb1d"
integrity sha512-1AX+Yt3icFuU6kxwmPakaiGrJUwG44MpuiqPg4dSolRFk6jmvs4b3IbUol9wKDLIgU76gevn3EwE8y/DkSJCZQ==
dependencies:
"@types/node" "*"
"@types/tar@^6.1.3":
version "6.1.3"
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-6.1.3.tgz#46a2ce7617950c4852dfd7e9cd41aa8161b9d750"
@ -2136,13 +2107,6 @@ browser-process-hrtime@^1.0.0:
resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
browserify-zlib@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d"
integrity sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==
dependencies:
pako "~0.2.0"
browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.4:
version "4.21.4"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987"
@ -2375,13 +2339,6 @@ clean-css@^5.2.2:
dependencies:
source-map "~0.6.0"
cli-progress@^3.11.2:
version "3.11.2"
resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.11.2.tgz#f8c89bd157e74f3f2c43bcfb3505670b4d48fc77"
integrity sha512-lCPoS6ncgX4+rJu5bS3F/iCz17kZ9MPZ6dpuTtI0KXKABkhyXIdYB3Inby1OpaGti3YlI3EeEkM9AuWpelJrVA==
dependencies:
string-width "^4.2.3"
cli-truncate@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7"
@ -3026,16 +2983,6 @@ duplexer3@^0.1.4:
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==
duplexify@^3.5.0, duplexify@^3.6.0:
version "3.7.1"
resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309"
integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==
dependencies:
end-of-stream "^1.0.0"
inherits "^2.0.1"
readable-stream "^2.0.0"
stream-shift "^1.0.0"
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@ -3138,7 +3085,7 @@ encodeurl@^1.0.2, encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==
end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@ -3641,10 +3588,10 @@ follow-redirects@^1.0.0:
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
fork-ts-checker-webpack-plugin@^7.2.14:
version "7.2.14"
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.14.tgz#746eb15b4d643aafccd3c729995f9c9281eabd22"
integrity sha512-Tg2feh/n8k486KX0EbXVUfJj3j0xnnbKYTJw0fnIb2QdV0+lblOYZSal5ed9hARoWVwKeOC7sYE2EakSRLo5ZA==
fork-ts-checker-webpack-plugin@^7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.3.0.tgz#a9c984a018493962360d7c7e77a67b44a2d5f3aa"
integrity sha512-IN+XTzusCjR5VgntYFgxbxVx3WraPRnKehBFrf00cMSrtUuW9MsG9dhL6MWpY6MkjC3wVwoujfCDgZZCQwbswA==
dependencies:
"@babel/code-frame" "^7.16.7"
chalk "^4.1.2"
@ -3668,15 +3615,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"
@ -3908,18 +3846,6 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4,
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
integrity sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==
gunzip-maybe@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/gunzip-maybe/-/gunzip-maybe-1.4.2.tgz#b913564ae3be0eda6f3de36464837a9cd94b98ac"
integrity sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==
dependencies:
browserify-zlib "^0.1.4"
is-deflate "^1.0.0"
is-gzip "^1.0.0"
peek-stream "^1.1.0"
pumpify "^1.3.3"
through2 "^2.0.3"
handle-thing@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
@ -4256,11 +4182,6 @@ is-core-module@^2.9.0:
dependencies:
has "^1.0.3"
is-deflate@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-deflate/-/is-deflate-1.0.0.tgz#c862901c3c161fb09dac7cdc7e784f80e98f2f14"
integrity sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==
is-docker@^2.0.0, is-docker@^2.1.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
@ -4288,11 +4209,6 @@ is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
is-gzip@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-gzip/-/is-gzip-1.0.0.tgz#6ca8b07b99c77998025900e555ced8ed80879a83"
integrity sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
@ -5234,9 +5150,9 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
brace-expansion "^1.1.7"
minimatch@^5.0.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff"
integrity sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==
version "5.1.6"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
@ -5598,11 +5514,6 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
pako@~0.2.0:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==
param-case@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
@ -5688,15 +5599,6 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
peek-stream@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67"
integrity sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==
dependencies:
buffer-from "^1.0.0"
duplexify "^3.5.0"
through2 "^2.0.3"
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
@ -5739,17 +5641,17 @@ pkg-dir@^4.2.0:
dependencies:
find-up "^4.0.0"
playwright-core@1.29.2:
version "1.29.2"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.29.2.tgz#2e8347e7e8522409f22b244e600e703b64022406"
integrity sha512-94QXm4PMgFoHAhlCuoWyaBYKb92yOcGVHdQLoxQ7Wjlc7Flg4aC/jbFW7xMR52OfXMVkWicue4WXE7QEegbIRA==
playwright-core@1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.30.0.tgz#de987cea2e86669e3b85732d230c277771873285"
integrity sha512-7AnRmTCf+GVYhHbLJsGUtskWTE33SwMZkybJ0v6rqR1boxq2x36U7p1vDRV7HO2IwTZgmycracLxPEJI49wu4g==
playwright@^1.29.2:
version "1.29.2"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.29.2.tgz#d6a0a3e8e44f023f7956ed19ffa8af915a042769"
integrity sha512-hKBYJUtdmYzcjdhYDkP9WGtORwwZBBKAW8+Lz7sr0ZMxtJr04ASXVzH5eBWtDkdb0c3LLFsehfPBTRfvlfKJOA==
playwright@^1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.30.0.tgz#b1d7be2d45d97fbb59f829f36f521f12010fe072"
integrity sha512-ENbW5o75HYB3YhnMTKJLTErIBExrSlX2ZZ1C/FzmHjUYIfxj/UnI+DWpQr992m+OQVSg0rCExAOlRwB+x+yyIg==
dependencies:
playwright-core "1.29.2"
playwright-core "1.30.0"
plist@^3.0.1, plist@^3.0.4:
version "3.0.6"
@ -5982,14 +5884,6 @@ pstree.remy@^1.1.8:
resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a"
integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==
pump@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
pump@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
@ -5998,15 +5892,6 @@ pump@^3.0.0:
end-of-stream "^1.1.0"
once "^1.3.1"
pumpify@^1.3.3:
version "1.5.1"
resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce"
integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==
dependencies:
duplexify "^3.6.0"
inherits "^2.0.3"
pump "^2.0.0"
punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
@ -6129,7 +6014,7 @@ read-config-file@6.2.0:
json5 "^2.2.0"
lazy-val "^1.0.4"
readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.2.2, readable-stream@~2.3.6:
readable-stream@^2.0.1, readable-stream@^2.2.2:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@ -6685,11 +6570,6 @@ statuses@2.0.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
stream-shift@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
string-length@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
@ -6933,14 +6813,6 @@ test-exclude@^6.0.0:
glob "^7.1.4"
minimatch "^3.0.4"
through2@^2.0.3:
version "2.0.5"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
dependencies:
readable-stream "~2.3.6"
xtend "~4.0.1"
thunky@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
@ -7530,7 +7402,7 @@ xmlchars@^2.2.0:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
xtend@^4.0.2, xtend@~4.0.1:
xtend@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==

View File

@ -1,6 +1,6 @@
{
"name": "@k8slens/release-tool",
"version": "6.4.0-alpha.2",
"version": "6.4.0-beta.8",
"description": "Release tool for lens monorepo",
"main": "dist/index.mjs",
"license": "MIT",
@ -12,7 +12,7 @@
},
"devDependencies": {
"@swc/cli": "^0.1.59",
"@swc/core": "^1.3.25",
"@swc/core": "^1.3.28",
"@types/command-line-args": "^5.2.0",
"@types/fs-extra": "^11.0.1",
"@types/node": "^16.18.11",

View File

@ -83,8 +83,7 @@ if (basename(process.cwd()) === "scripts") {
console.error(errorMessages.wrongCwd);
}
const packageJson = await fse.readJson("./package.json");
const currentVersion = new SemVer(packageJson.version);
const currentVersion = new SemVer((await fse.readJson("./lerna.json")).version);
console.log(`current version: ${currentVersion.format()}`);

View File

@ -40,71 +40,71 @@
slash "3.0.0"
source-map "^0.7.3"
"@swc/core-darwin-arm64@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.25.tgz#01ce7b8a88b545a4fc5283ed6f96b22c5733d6c4"
integrity sha512-8PWAVcjTJyj2VrqPBFOIi2w2P0Z8kOCbzHW3+pe+bSXxfGMG0MKPl5U2IXhsEL0ovm4xSFlqW0yygpoP3MmRPw==
"@swc/core-darwin-arm64@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.28.tgz#3ab15dd6f0ede5b3c7d6ed557a26c0fad34ee5c9"
integrity sha512-f1ph5DDIOX6bvjhlOuWz8ZDiTghhq144Sy9gaRi+DjK3gdnftc4p5AyZHA4Xb03MZ+fd0mj8q6/znco5aBMi1A==
"@swc/core-darwin-x64@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.25.tgz#9fad102c507011f42c5a5d1f84919b81ab96d7f8"
integrity sha512-5DHGiMYFEj5aa208tCjo7Sn5tiG4xPz+4gUiWVlglxqXFptkNim5xu/1G6VYm5Zk7dI5jJkjTU76GQG7IRvPug==
"@swc/core-darwin-x64@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.28.tgz#e0eaa0eb763bc7def581df93b1a5df1249eb5528"
integrity sha512-5dB5Z4Ry45UTXXAxhwagCYfh57njffkdIJkjid1f+Qt4i7cOznOaIiD4wobGD7xHCATEcs8F23yWkAmvrbacew==
"@swc/core-linux-arm-gnueabihf@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.25.tgz#ecf3a34899fdbdc742523524caab29c0db97a6ad"
integrity sha512-YNfLxv9PhZk+jrJbpR1mMrYBUkufo0hiFv3S1OrX3l8edsIP4wPND5w9ZH0Oi898f6Jg9DBrY2zXJMQ+gWkbvA==
"@swc/core-linux-arm-gnueabihf@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.28.tgz#f7038e60bddebc6b0c0aa444c50157fe4908fb58"
integrity sha512-VmtAQAENJ5SHBXTKxXNlnnM34xGOtJpHYva83zeZM/2epdoz1BJ6Ny3gTBXDftaWgAj2SRwVIjMR3/c71aJysQ==
"@swc/core-linux-arm64-gnu@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.25.tgz#50524c9db2dbf874570e45f0a66e0283f02bc2d9"
integrity sha512-kS+spM5/xQ6QvWF1ms3byfjnhUlpjTfFwgCyHnIKgjvsYkDa+vkAIhKq6HuEdaTPaCRCjts0Zarhub1nClUU0g==
"@swc/core-linux-arm64-gnu@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.28.tgz#6e3013176c4cc5dd006c848911e3bccaf1fa77dd"
integrity sha512-KIJ1SHGbusM6W2rxue1f+IN/iuzmspgMY9qP/qW5Z43Mm9mrHdzDmhsMoEH1y2gPUsu/ZZnkXlODJ0M0454JNQ==
"@swc/core-linux-arm64-musl@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.25.tgz#f04a3d3784cff14f96ad9901861485ec0fa14ebf"
integrity sha512-vM3D7LWmjotUAJ2D4F+L+dspFeWrcPNVh0o8TCoTOYCt8DPD5YsUKTpIgOsZ+gReeWUAnNTh0Btx5pGGVfajGA==
"@swc/core-linux-arm64-musl@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.28.tgz#01896d81f967104fb851534962dd344252d85025"
integrity sha512-Zz2DZj8ncSvVEAsol8gtoXrVLP8e+IYSx6o8txYVR0p0pviJBzeuYGaLe5sbQdQnVVS2M5N90LX28P6/mQb6sQ==
"@swc/core-linux-x64-gnu@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.25.tgz#761fb020b8a0130e4dccc9c8dce355fa06df63f4"
integrity sha512-xUCLLMDlYa/zB8BftVa4SrxuVpcDxkltCfmBg5r2pZPVskhC5ZJsQZ/AvWNChoAB11shRhjTaWDlmxJEsa7TIg==
"@swc/core-linux-x64-gnu@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.28.tgz#03d9b0171267ccc5d0efd2a939150f5d1da550ae"
integrity sha512-Za3uowhcP74qSCNqjZLBx3nAmjIFYNbB0nGBKwkLBopbMcpO0BjvnsdzmoWqv2Uq41vaeVk/o9vATQMojfHHQg==
"@swc/core-linux-x64-musl@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.25.tgz#f944ee48c972ebdcb3e6d6fd62d67eb98dbb1268"
integrity sha512-QzHU3BIaUVRSFNsUn3Qxx1vgtF/f5NqsFMAAPSq9Y8Yq5nrlc2t7cNuOROxHLbUqE+NPUp6+RglleJMoeWz5mA==
"@swc/core-linux-x64-musl@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.28.tgz#6badfc87d94b7891c11aa71496498d2ff29535db"
integrity sha512-i3BAkmrf19VXybbjuS9Jnlnx5Ie4vukLMCQRfXCQqIqaiSw3QzubjolYo07sGtzoVI3nBscDt3i8T+oxTPOMkw==
"@swc/core-win32-arm64-msvc@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.25.tgz#af63ae850ef6e7322e8a5a0959529e96096239d2"
integrity sha512-77VSVtneVOAUL4zkRyQZ6pWVpTsVVdqwly/DKnRnloglGKxYuk5DG5MUBsL72Nnfv4OCHjZ27eI3NUrpLsUb2Q==
"@swc/core-win32-arm64-msvc@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.28.tgz#2441d2cdbc313618332de014be0c6c3573931b62"
integrity sha512-DdNxKP/P0/OFqX1dtl9Ubrd567QPMSeJvp9iDtMdgCBWN2N6HXvyMj623WIA0y9FIcA7wexz0Hh3gS+G9Jof+Q==
"@swc/core-win32-ia32-msvc@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.25.tgz#96a869aa4b4c41c44c9c9893ac4aad68d1233022"
integrity sha512-kz0v3K3H6OPEZR3ry72Ad/6C5GrZBRRUk69K58LORQ8tZXQD3UGl85pUbQqyHl8fR5NU76Muxgovj9CI9iTHGA==
"@swc/core-win32-ia32-msvc@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.28.tgz#82319fcff87289e3e9439dd76524a7bdfe58f5fa"
integrity sha512-/jZWBIgaNkKTlKiZ7DXmMJzW0n1ychDKS1bYRuNLrtTRthMP5M3LRZXITz0AcvPl0mIA0IXeMQbE4ZMUc7LAFg==
"@swc/core-win32-x64-msvc@1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.25.tgz#9035c11626653322a404f3f44af11a02d989094c"
integrity sha512-nmQOAzIpNRRnupWzkenJmW4i+h1M76cVNUqEU2MjmtesEkRZEGqv//jefXiyCP2zcbeLNLKiB2ptVJhpd1BvRA==
"@swc/core-win32-x64-msvc@1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.28.tgz#a2067da2f3f4f95ef1b05eb86941d0609a66e9c6"
integrity sha512-HKhE0LznEwTP/qi6EVclmJzfNdykzuK6sjYMTjcDqNJOuuRNMu+IJzPzCPuakgljymWGFmddnuuubd9Y+kl3eg==
"@swc/core@^1.3.25":
version "1.3.25"
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.25.tgz#53786ea51fac319684d6822de1738eb55b73a4b7"
integrity sha512-wqzvM/wu6OsTVYPMStOpm7kIQcPX3GoZ0sC85qzDdsCxmJ1rmItLAD91sXPUmmdk0XqPYjLgT9MRDEIP5woz4g==
"@swc/core@^1.3.28":
version "1.3.28"
resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.28.tgz#e0fc1fd15b2e7e01d0f16d55eb60b74e65fb1025"
integrity sha512-yzc61HbAIjHeOYTUW/IgXAywlSviMFymnUiLY7dNUELGHjMVxSp0XnIlPQN4v5UekYbwLEV8+KChaoQRACiQCw==
optionalDependencies:
"@swc/core-darwin-arm64" "1.3.25"
"@swc/core-darwin-x64" "1.3.25"
"@swc/core-linux-arm-gnueabihf" "1.3.25"
"@swc/core-linux-arm64-gnu" "1.3.25"
"@swc/core-linux-arm64-musl" "1.3.25"
"@swc/core-linux-x64-gnu" "1.3.25"
"@swc/core-linux-x64-musl" "1.3.25"
"@swc/core-win32-arm64-msvc" "1.3.25"
"@swc/core-win32-ia32-msvc" "1.3.25"
"@swc/core-win32-x64-msvc" "1.3.25"
"@swc/core-darwin-arm64" "1.3.28"
"@swc/core-darwin-x64" "1.3.28"
"@swc/core-linux-arm-gnueabihf" "1.3.28"
"@swc/core-linux-arm64-gnu" "1.3.28"
"@swc/core-linux-arm64-musl" "1.3.28"
"@swc/core-linux-x64-gnu" "1.3.28"
"@swc/core-linux-x64-musl" "1.3.28"
"@swc/core-win32-arm64-msvc" "1.3.28"
"@swc/core-win32-ia32-msvc" "1.3.28"
"@swc/core-win32-x64-msvc" "1.3.28"
"@types/command-line-args@^5.2.0":
version "5.2.0"

2
packages/semver/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
dist/
node_modules/

View File

@ -0,0 +1,23 @@
{
"name": "@k8slens/semver",
"version": "6.4.0-beta.8",
"description": "CLI over semver package for picking parts of a version",
"main": "dist/index.mjs",
"license": "MIT",
"private": true,
"scripts": {
"clean": "rm -rf dist/",
"build": "swc ./src/index.ts -o ./dist/index.mjs"
},
"dependencies": {
"command-line-args": "^5.2.1",
"semver": "^7.3.8"
},
"devDependencies": {
"@swc/cli": "^0.1.59",
"@swc/core": "^1.3.28",
"@types/command-line-args": "^5.2.0",
"@types/node": "^16.18.11",
"@types/semver": "^7.3.13"
}
}

View File

@ -0,0 +1,91 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { SemVer } from "semver";
import commandLineArgs from "command-line-args";
const options = commandLineArgs([
{
name: "version",
defaultOption: true,
},
{
name: "major",
type: Boolean,
},
{
name: "minor",
type: Boolean,
},
{
name: "patch",
type: Boolean,
},
{
name: "prerelease",
type: (input) => {
if (!input || input === "true") {
return true;
}
const asNumber = Number(input);
if (Number.isInteger(asNumber) && asNumber >= 0) {
return asNumber;
}
throw new Error("Invalid --prerelease value, must be either true (default), or a non-negative integrer");
},
},
{
name: "json",
type: Boolean,
},
]);
if (!options.version || typeof options.version !== "string") {
console.error("Missing version");
process.exit(1);
}
const showMajor = Boolean(options.major);
const showMinor = Boolean(options.minor);
const showPatch = Boolean(options.patch);
const showPrerelease = options.prerelease !== undefined;
const showJson = Boolean(options.json);
const showOptionsSet = [+showMajor, +showMinor, +showPatch, +showPrerelease, +showJson].reduce((prev, cur) => prev + cur, 0);
if (showOptionsSet === 0) {
console.error("One of the following must be provided: --major, --minor, --patch, --prerelease, --json");
process.exit(1);
}
if (showOptionsSet > 1) {
console.error("Only one of the following may be provided: --major, --minor, --patch, --prerelease, --json");
process.exit(1);
}
const version = new SemVer(options.version);
if (showMajor) {
console.log(version.major.toString());
} else if (showMinor) {
console.log(version.major.toString());
} else if (showPatch) {
console.log(version.patch.toString());
} else if (showPrerelease) {
if ((options.prerelease ?? true) === true) {
console.log(JSON.stringify(version.prerelease))
} else if (version.prerelease.length > options.prerelease) {
console.log(version.prerelease[options.prerelease].toString());
}
} else if (showJson) {
console.log(JSON.stringify({
major: version.major,
minor: version.minor,
patch: version.patch,
prerelease: version.prerelease,
}));
}

Some files were not shown because too many files have changed in this diff Show More