mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Merge branch 'master' into app-modal-registry
This commit is contained in:
commit
136823ce18
35
.github/workflows/bump-master-version.yaml
vendored
Normal file
35
.github/workflows/bump-master-version.yaml
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
name: Bump Version on master
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
release:
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release') }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout Release from lens
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
npm i --location=global semver
|
||||||
|
- name: Bump version to first alpha of next minor version
|
||||||
|
run: |
|
||||||
|
NEW_VERSION=$(cat package.json | jq .version --raw-output| xargs semver -i preminor --preid alpha)
|
||||||
|
cat package.json | jq --arg new_version "$NEW_VERSION" '.version = $new_version' > new-package.json
|
||||||
|
mv new-package.json package.json
|
||||||
|
- uses: peter-evans/create-pull-request@v4
|
||||||
|
with:
|
||||||
|
add-paths: package.json
|
||||||
|
commit-message: Update package.json version to next preminor because of recent release
|
||||||
|
signoff: true
|
||||||
|
delete-branch: true
|
||||||
|
title: Update version to next preminor
|
||||||
|
labels: chore
|
||||||
6
.github/workflows/mkdocs-manual.yml
vendored
6
.github/workflows/mkdocs-manual.yml
vendored
@ -53,9 +53,9 @@ jobs:
|
|||||||
rm -fr ./docs/clusters ./docs/contributing ./docs/faq ./docs/getting-started ./docs/helm ./docs/support ./docs/supporting
|
rm -fr ./docs/clusters ./docs/contributing ./docs/faq ./docs/getting-started ./docs/helm ./docs/support ./docs/supporting
|
||||||
sed -i '/Protocol Handlers/d' ./mkdocs.yml
|
sed -i '/Protocol Handlers/d' ./mkdocs.yml
|
||||||
sed -i '/IPC/d' ./mkdocs.yml
|
sed -i '/IPC/d' ./mkdocs.yml
|
||||||
sed -i 's#../../clusters/adding-clusters.md#https://docs.k8slens.dev/latest/clusters/adding-clusters/#g' ./docs/extensions/get-started/your-first-extension.md
|
sed -i 's#../../clusters/adding-clusters.md#https://docs.k8slens.dev/getting-started/add-cluster/#g' ./docs/extensions/get-started/your-first-extension.md
|
||||||
sed -i 's#clusters/adding-clusters.md#https://docs.k8slens.dev/latest/clusters/adding-clusters/#g' ./docs/README.md
|
sed -i 's#clusters/adding-clusters.md#https://docs.k8slens.dev//getting-started/adding-clusters/#g' ./docs/README.md
|
||||||
sed -i 's#../../contributing/README.md#https://docs.k8slens.dev/latest/contributing/#g' ./docs/extensions/guides/generator.md
|
sed -i 's#../../contributing/README.md#https://docs.k8slens.dev/contributing/#g' ./docs/extensions/guides/generator.md
|
||||||
|
|
||||||
- name: git config
|
- name: git config
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
14
.github/workflows/require-milestone.yml
vendored
Normal file
14
.github/workflows/require-milestone.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
name: Require Milestone
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, edited, synchronize]
|
||||||
|
jobs:
|
||||||
|
milestone:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Require Milestone
|
||||||
|
run: |
|
||||||
|
exit $(gh pr view ${{ github.event.pull_request.number }} --json milestone | jq 'if .milestone == null then 1 else 0 end')
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||||
@ -1,3 +1,3 @@
|
|||||||
# Contributing to Lens
|
# Contributing to Lens
|
||||||
|
|
||||||
See [Contributing to Lens](https://docs.k8slens.dev/latest/contributing/) documentation.
|
See [Contributing to Lens](https://docs.k8slens.dev/contributing/) documentation.
|
||||||
|
|||||||
@ -19,15 +19,15 @@ Lens IDE a standalone application for MacOS, Windows and Linux operating systems
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
See [Getting Started](https://docs.k8slens.dev/main/getting-started/install-lens/) page.
|
See [Getting Started](https://docs.k8slens.dev/getting-started/install-lens/) page.
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
See [Development](https://docs.k8slens.dev/latest/contributing/development/) page.
|
See [Development](https://docs.k8slens.dev/contributing/development/) page.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
See [Contributing](https://docs.k8slens.dev/latest/contributing/) page.
|
See [Contributing](https://docs.k8slens.dev/contributing/) page.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@ -78,7 +78,7 @@ npm run dev
|
|||||||
You must restart Lens for the extension to load.
|
You must restart Lens for the extension to load.
|
||||||
After this initial restart, reload Lens and it will automatically pick up changes any time the extension rebuilds.
|
After this initial restart, reload Lens and it will automatically pick up changes any time the extension rebuilds.
|
||||||
|
|
||||||
With Lens running, either connect to an existing cluster or create a new one - refer to the latest [Lens Documentation](https://docs.k8slens.dev/main/catalog/) for details on how to add a cluster in Lens IDE.
|
With Lens running, either connect to an existing cluster or create a new one - refer to the latest [Lens Documentation](https://docs.k8slens.dev/getting-started/add-cluster/) for details on how to add a cluster in Lens IDE.
|
||||||
You will see the "Hello World" page in the left-side cluster menu.
|
You will see the "Hello World" page in the left-side cluster menu.
|
||||||
|
|
||||||
## Develop the Extension
|
## Develop the Extension
|
||||||
|
|||||||
@ -46,14 +46,14 @@ Open `my-first-lens-ext/renderer.tsx` and change the value of `title` from `"Hel
|
|||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
clusterPageMenus = [
|
clusterPageMenus = [
|
||||||
{
|
{
|
||||||
target: { pageId: "hello" },
|
target: { pageId: "hello" },
|
||||||
title: "Hello Lens",
|
title: "Hello Lens",
|
||||||
components: {
|
components: {
|
||||||
Icon: ExampleIcon,
|
Icon: ExampleIcon,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
]
|
];
|
||||||
```
|
```
|
||||||
|
|
||||||
Reload Lens and you will see that the menu item text has changed to "Hello Lens".
|
Reload Lens and you will see that the menu item text has changed to "Hello Lens".
|
||||||
@ -70,6 +70,6 @@ To debug your extension, please see our instructions on [Testing Extensions](../
|
|||||||
To dive deeper, consider looking at [Common Capabilities](../capabilities/common-capabilities.md), [Styling](../capabilities/styling.md), or [Extension Anatomy](anatomy.md).
|
To dive deeper, consider looking at [Common Capabilities](../capabilities/common-capabilities.md), [Styling](../capabilities/styling.md), or [Extension Anatomy](anatomy.md).
|
||||||
|
|
||||||
If you find problems with the Lens Extension Generator, or have feature requests, you are welcome to raise an [issue](https://github.com/lensapp/generator-lens-ext/issues).
|
If you find problems with the Lens Extension Generator, or have feature requests, you are welcome to raise an [issue](https://github.com/lensapp/generator-lens-ext/issues).
|
||||||
You can find the latest Lens contribution guidelines [here](https://docs.k8slens.dev/latest/contributing).
|
You can find the latest Lens contribution guidelines [here](https://docs.k8slens.dev/contributing).
|
||||||
|
|
||||||
The Generator source code is hosted at [GitHub](https://github.com/lensapp/generator-lens-ext).
|
The Generator source code is hosted at [GitHub](https://github.com/lensapp/generator-lens-ext).
|
||||||
|
|||||||
@ -771,7 +771,7 @@ Construct the table using the `Renderer.Component.Table` and related elements.
|
|||||||
|
|
||||||
For each pod the name, age, and status are obtained using the `Renderer.K8sApi.Pod` methods.
|
For each pod the name, age, and status are obtained using the `Renderer.K8sApi.Pod` methods.
|
||||||
The table is constructed using the `Renderer.Component.Table` and related elements.
|
The table is constructed using the `Renderer.Component.Table` and related elements.
|
||||||
See [Component documentation](https://docs.k8slens.dev/latest/extensions/api/modules/_renderer_api_components_/) for further details.
|
See [Component documentation](https://api-docs.k8slens.dev/latest/extensions/api/modules/Renderer.Component/) for further details.
|
||||||
|
|
||||||
### `kubeObjectStatusTexts`
|
### `kubeObjectStatusTexts`
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
prometheus+:: {
|
kubernetesControlPlane+:: {
|
||||||
serviceMonitorKubelet+: {
|
serviceMonitorKubelet+: {
|
||||||
spec+: {
|
spec+: {
|
||||||
endpoints: std.map(function(endpoint)
|
endpoints: std.map(function(endpoint)
|
||||||
|
|||||||
39
package.json
39
package.json
@ -3,7 +3,7 @@
|
|||||||
"productName": "OpenLens",
|
"productName": "OpenLens",
|
||||||
"description": "OpenLens - Open Source IDE for Kubernetes",
|
"description": "OpenLens - Open Source IDE for Kubernetes",
|
||||||
"homepage": "https://github.com/lensapp/lens",
|
"homepage": "https://github.com/lensapp/lens",
|
||||||
"version": "6.1.0",
|
"version": "6.2.0-alpha.0",
|
||||||
"main": "static/build/main.js",
|
"main": "static/build/main.js",
|
||||||
"copyright": "© 2022 OpenLens Authors",
|
"copyright": "© 2022 OpenLens Authors",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -246,7 +246,7 @@
|
|||||||
"history": "^4.10.1",
|
"history": "^4.10.1",
|
||||||
"http-proxy": "^1.18.1",
|
"http-proxy": "^1.18.1",
|
||||||
"immer": "^9.0.15",
|
"immer": "^9.0.15",
|
||||||
"joi": "^17.6.2",
|
"joi": "^17.6.3",
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jsdom": "^16.7.0",
|
"jsdom": "^16.7.0",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
@ -259,7 +259,7 @@
|
|||||||
"mobx-utils": "^6.0.4",
|
"mobx-utils": "^6.0.4",
|
||||||
"mock-fs": "^5.1.4",
|
"mock-fs": "^5.1.4",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"moment-timezone": "^0.5.37",
|
"moment-timezone": "^0.5.38",
|
||||||
"monaco-editor": "^0.29.1",
|
"monaco-editor": "^0.29.1",
|
||||||
"monaco-editor-webpack-plugin": "^5.0.0",
|
"monaco-editor-webpack-plugin": "^5.0.0",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
@ -298,10 +298,10 @@
|
|||||||
"@material-ui/core": "^4.12.3",
|
"@material-ui/core": "^4.12.3",
|
||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@material-ui/lab": "^4.0.0-alpha.60",
|
"@material-ui/lab": "^4.0.0-alpha.60",
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.8",
|
||||||
"@sentry/types": "^6.19.7",
|
"@sentry/types": "^6.19.7",
|
||||||
"@swc/cli": "^0.1.57",
|
"@swc/cli": "^0.1.57",
|
||||||
"@swc/core": "^1.3.5",
|
"@swc/core": "^1.3.9",
|
||||||
"@swc/jest": "^0.2.23",
|
"@swc/jest": "^0.2.23",
|
||||||
"@testing-library/dom": "^7.31.2",
|
"@testing-library/dom": "^7.31.2",
|
||||||
"@testing-library/jest-dom": "^5.16.5",
|
"@testing-library/jest-dom": "^5.16.5",
|
||||||
@ -331,7 +331,7 @@
|
|||||||
"@types/md5-file": "^4.0.2",
|
"@types/md5-file": "^4.0.2",
|
||||||
"@types/mini-css-extract-plugin": "^2.4.0",
|
"@types/mini-css-extract-plugin": "^2.4.0",
|
||||||
"@types/mock-fs": "^4.13.1",
|
"@types/mock-fs": "^4.13.1",
|
||||||
"@types/node": "^16.11.64",
|
"@types/node": "^16.11.68",
|
||||||
"@types/node-fetch": "^2.6.2",
|
"@types/node-fetch": "^2.6.2",
|
||||||
"@types/npm": "^2.0.32",
|
"@types/npm": "^2.0.32",
|
||||||
"@types/proper-lockfile": "^4.1.2",
|
"@types/proper-lockfile": "^4.1.2",
|
||||||
@ -350,7 +350,7 @@
|
|||||||
"@types/semver": "^7.3.12",
|
"@types/semver": "^7.3.12",
|
||||||
"@types/sharp": "^0.31.0",
|
"@types/sharp": "^0.31.0",
|
||||||
"@types/spdy": "^3.4.5",
|
"@types/spdy": "^3.4.5",
|
||||||
"@types/tar": "^6.1.2",
|
"@types/tar": "^6.1.3",
|
||||||
"@types/tar-stream": "^2.2.2",
|
"@types/tar-stream": "^2.2.2",
|
||||||
"@types/tcp-port-used": "^1.0.1",
|
"@types/tcp-port-used": "^1.0.1",
|
||||||
"@types/tempy": "^0.3.0",
|
"@types/tempy": "^0.3.0",
|
||||||
@ -361,8 +361,8 @@
|
|||||||
"@types/webpack-dev-server": "^4.7.2",
|
"@types/webpack-dev-server": "^4.7.2",
|
||||||
"@types/webpack-env": "^1.18.0",
|
"@types/webpack-env": "^1.18.0",
|
||||||
"@types/webpack-node-externals": "^2.5.3",
|
"@types/webpack-node-externals": "^2.5.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.39.0",
|
"@typescript-eslint/eslint-plugin": "^5.40.1",
|
||||||
"@typescript-eslint/parser": "^5.39.0",
|
"@typescript-eslint/parser": "^5.40.1",
|
||||||
"adr": "^1.4.3",
|
"adr": "^1.4.3",
|
||||||
"ansi_up": "^5.1.0",
|
"ansi_up": "^5.1.0",
|
||||||
"chart.js": "^2.9.4",
|
"chart.js": "^2.9.4",
|
||||||
@ -374,18 +374,17 @@
|
|||||||
"css-loader": "^6.7.1",
|
"css-loader": "^6.7.1",
|
||||||
"deepdash": "^5.3.9",
|
"deepdash": "^5.3.9",
|
||||||
"dompurify": "^2.4.0",
|
"dompurify": "^2.4.0",
|
||||||
"electron": "^19.1.1",
|
"electron": "^19.1.3",
|
||||||
"electron-builder": "^23.3.3",
|
"electron-builder": "^23.6.0",
|
||||||
"electron-notarize": "^0.3.0",
|
"electron-notarize": "^0.3.0",
|
||||||
"esbuild": "^0.15.10",
|
"esbuild": "^0.15.12",
|
||||||
"esbuild-loader": "^2.20.0",
|
"esbuild-loader": "^2.20.0",
|
||||||
"eslint": "^8.24.0",
|
"eslint": "^8.25.0",
|
||||||
"eslint-plugin-header": "^3.1.1",
|
"eslint-plugin-header": "^3.1.1",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"eslint-plugin-react": "7.31.8",
|
"eslint-plugin-react": "7.31.10",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"eslint-plugin-unused-imports": "^2.0.0",
|
"eslint-plugin-unused-imports": "^2.0.0",
|
||||||
"flex.box": "^3.4.4",
|
|
||||||
"fork-ts-checker-webpack-plugin": "^6.5.2",
|
"fork-ts-checker-webpack-plugin": "^6.5.2",
|
||||||
"gunzip-maybe": "^1.4.2",
|
"gunzip-maybe": "^1.4.2",
|
||||||
"html-webpack-plugin": "^5.5.0",
|
"html-webpack-plugin": "^5.5.0",
|
||||||
@ -402,8 +401,8 @@
|
|||||||
"node-gyp": "^8.3.0",
|
"node-gyp": "^8.3.0",
|
||||||
"node-loader": "^2.0.0",
|
"node-loader": "^2.0.0",
|
||||||
"nodemon": "^2.0.20",
|
"nodemon": "^2.0.20",
|
||||||
"playwright": "^1.26.1",
|
"playwright": "^1.27.1",
|
||||||
"postcss": "^8.4.17",
|
"postcss": "^8.4.18",
|
||||||
"postcss-loader": "^6.2.1",
|
"postcss-loader": "^6.2.1",
|
||||||
"query-string": "^7.1.1",
|
"query-string": "^7.1.1",
|
||||||
"randomcolor": "^0.6.2",
|
"randomcolor": "^0.6.2",
|
||||||
@ -411,7 +410,7 @@
|
|||||||
"react-refresh": "^0.14.0",
|
"react-refresh": "^0.14.0",
|
||||||
"react-refresh-typescript": "^2.0.7",
|
"react-refresh-typescript": "^2.0.7",
|
||||||
"react-router-dom": "^5.3.4",
|
"react-router-dom": "^5.3.4",
|
||||||
"react-select": "^5.4.0",
|
"react-select": "^5.5.4",
|
||||||
"react-select-event": "^5.5.1",
|
"react-select-event": "^5.5.1",
|
||||||
"react-table": "^7.8.0",
|
"react-table": "^7.8.0",
|
||||||
"react-window": "^1.8.7",
|
"react-window": "^1.8.7",
|
||||||
@ -419,13 +418,13 @@
|
|||||||
"sass-loader": "^12.6.0",
|
"sass-loader": "^12.6.0",
|
||||||
"sharp": "^0.31.1",
|
"sharp": "^0.31.1",
|
||||||
"style-loader": "^3.3.1",
|
"style-loader": "^3.3.1",
|
||||||
"tailwindcss": "^3.1.8",
|
"tailwindcss": "^3.2.0",
|
||||||
"tar-stream": "^2.2.0",
|
"tar-stream": "^2.2.0",
|
||||||
"ts-loader": "^9.4.1",
|
"ts-loader": "^9.4.1",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"type-fest": "^2.14.0",
|
"type-fest": "^2.14.0",
|
||||||
"typed-emitter": "^1.4.0",
|
"typed-emitter": "^1.4.0",
|
||||||
"typedoc": "0.23.15",
|
"typedoc": "0.23.17",
|
||||||
"typedoc-plugin-markdown": "^3.13.6",
|
"typedoc-plugin-markdown": "^3.13.6",
|
||||||
"typescript": "^4.8.4",
|
"typescript": "^4.8.4",
|
||||||
"typescript-plugin-css-modules": "^3.4.0",
|
"typescript-plugin-css-modules": "^3.4.0",
|
||||||
|
|||||||
@ -1,22 +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 { AppPaths } from "./app-path-injection-token";
|
|
||||||
import type { RequestChannel } from "../utils/channel/request-channel-injection-token";
|
|
||||||
import { messageChannelInjectionToken } from "../utils/channel/message-channel-injection-token";
|
|
||||||
|
|
||||||
export type AppPathsChannel = RequestChannel<void, AppPaths>;
|
|
||||||
|
|
||||||
const appPathsChannelInjectable = getInjectable({
|
|
||||||
id: "app-paths-channel",
|
|
||||||
|
|
||||||
instantiate: (): AppPathsChannel => ({
|
|
||||||
id: "app-paths",
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: messageChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default appPathsChannelInjectable;
|
|
||||||
13
src/common/app-paths/app-paths-channel.ts
Normal file
13
src/common/app-paths/app-paths-channel.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { AppPaths } from "./app-path-injection-token";
|
||||||
|
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type AppPathsChannel = RequestChannel<void, AppPaths>;
|
||||||
|
|
||||||
|
export const appPathsChannel: AppPathsChannel = {
|
||||||
|
id: "app-paths",
|
||||||
|
};
|
||||||
|
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { MessageChannel } from "../utils/channel/message-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type RestartAndInstallUpdateChannel = MessageChannel<void>;
|
||||||
|
|
||||||
|
export const restartAndInstallUpdateChannel: RestartAndInstallUpdateChannel = {
|
||||||
|
id: "restart-and-install-update-channel",
|
||||||
|
};
|
||||||
@ -1,21 +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 { MessageChannel } from "../../utils/channel/message-channel-injection-token";
|
|
||||||
import { messageChannelInjectionToken } from "../../utils/channel/message-channel-injection-token";
|
|
||||||
|
|
||||||
export type RestartAndInstallUpdateChannel = MessageChannel;
|
|
||||||
|
|
||||||
const restartAndInstallUpdateChannel = getInjectable({
|
|
||||||
id: "restart-and-install-update-channel",
|
|
||||||
|
|
||||||
instantiate: (): RestartAndInstallUpdateChannel => ({
|
|
||||||
id: "restart-and-install-update-channel",
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: messageChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default restartAndInstallUpdateChannel;
|
|
||||||
@ -19,7 +19,7 @@ const selectedUpdateChannelInjectable = getInjectable({
|
|||||||
|
|
||||||
instantiate: (di): SelectedUpdateChannel => {
|
instantiate: (di): SelectedUpdateChannel => {
|
||||||
const defaultUpdateChannel = di.inject(defaultUpdateChannelInjectable);
|
const defaultUpdateChannel = di.inject(defaultUpdateChannelInjectable);
|
||||||
const state = observable.box<UpdateChannel>();
|
const state = observable.box<UpdateChannel>(undefined, { deep: false });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
value: computed(() => state.get() ?? defaultUpdateChannel.get()),
|
value: computed(() => state.get() ?? defaultUpdateChannel.get()),
|
||||||
|
|||||||
56
src/common/fetch/download-binary.injectable.ts
Normal file
56
src/common/fetch/download-binary.injectable.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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 { RequestInit, Response } from "node-fetch";
|
||||||
|
import type { AsyncResult } from "../utils/async-result";
|
||||||
|
import fetchInjectable from "./fetch.injectable";
|
||||||
|
|
||||||
|
export interface DownloadBinaryOptions {
|
||||||
|
signal?: AbortSignal | null | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DownloadBinary = (url: string, opts?: DownloadBinaryOptions) => Promise<AsyncResult<Buffer, string>>;
|
||||||
|
|
||||||
|
const downloadBinaryInjectable = getInjectable({
|
||||||
|
id: "download-binary",
|
||||||
|
instantiate: (di): DownloadBinary => {
|
||||||
|
const fetch = di.inject(fetchInjectable);
|
||||||
|
|
||||||
|
return async (url, opts) => {
|
||||||
|
let result: Response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// TODO: upgrade node-fetch once we switch to ESM
|
||||||
|
result = await fetch(url, opts as RequestInit);
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: false,
|
||||||
|
error: String(error),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.status < 200 || 300 <= result.status) {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: false,
|
||||||
|
error: result.statusText,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: true,
|
||||||
|
response: await result.buffer(),
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: false,
|
||||||
|
error: String(error),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default downloadBinaryInjectable;
|
||||||
56
src/common/fetch/download-json.injectable.ts
Normal file
56
src/common/fetch/download-json.injectable.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* 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 { RequestInit, Response } from "node-fetch";
|
||||||
|
import type { JsonValue } from "type-fest";
|
||||||
|
import type { AsyncResult } from "../utils/async-result";
|
||||||
|
import fetchInjectable from "./fetch.injectable";
|
||||||
|
|
||||||
|
export interface DownloadJsonOptions {
|
||||||
|
signal?: AbortSignal | null | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DownloadJson = (url: string, opts?: DownloadJsonOptions) => Promise<AsyncResult<JsonValue, string>>;
|
||||||
|
|
||||||
|
const downloadJsonInjectable = getInjectable({
|
||||||
|
id: "download-json",
|
||||||
|
instantiate: (di): DownloadJson => {
|
||||||
|
const fetch = di.inject(fetchInjectable);
|
||||||
|
|
||||||
|
return async (url, opts) => {
|
||||||
|
let result: Response;
|
||||||
|
|
||||||
|
try {
|
||||||
|
result = await fetch(url, opts as RequestInit);
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: false,
|
||||||
|
error: String(error),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.status < 200 || 300 <= result.status) {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: false,
|
||||||
|
error: result.statusText,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: true,
|
||||||
|
response: await result.json(),
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
callWasSuccessful: false,
|
||||||
|
error: String(error),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default downloadJsonInjectable;
|
||||||
@ -3,10 +3,10 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { RequestInfo, RequestInit, Response } from "node-fetch";
|
|
||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
|
import type { RequestInit, Response } from "node-fetch";
|
||||||
|
|
||||||
export type Fetch = (url: RequestInfo, init?: RequestInit) => Promise<Response>;
|
export type Fetch = (url: string, init?: RequestInit) => Promise<Response>;
|
||||||
|
|
||||||
const fetchInjectable = getInjectable({
|
const fetchInjectable = getInjectable({
|
||||||
id: "fetch",
|
id: "fetch",
|
||||||
|
|||||||
17
src/common/fetch/timeout-controller.ts
Normal file
17
src/common/fetch/timeout-controller.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an AbortController with an associated timeout
|
||||||
|
* @param timeout The number of milliseconds before this controller will auto abort
|
||||||
|
*/
|
||||||
|
export function withTimeout(timeout: number): AbortController {
|
||||||
|
const controller = new AbortController();
|
||||||
|
const id = setTimeout(() => controller.abort(), timeout);
|
||||||
|
|
||||||
|
controller.signal.addEventListener("abort", () => clearTimeout(id));
|
||||||
|
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
@ -1,22 +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 { IpcRendererNavigationEvents } from "../../renderer/navigation/events";
|
|
||||||
import type { MessageChannel } from "../utils/channel/message-channel-injection-token";
|
|
||||||
import { messageChannelInjectionToken } from "../utils/channel/message-channel-injection-token";
|
|
||||||
|
|
||||||
export type AppNavigationChannel = MessageChannel<string>;
|
|
||||||
|
|
||||||
const appNavigationChannelInjectable = getInjectable({
|
|
||||||
id: "app-navigation-channel",
|
|
||||||
|
|
||||||
instantiate: (): AppNavigationChannel => ({
|
|
||||||
id: IpcRendererNavigationEvents.NAVIGATE_IN_APP,
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: messageChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default appNavigationChannelInjectable;
|
|
||||||
12
src/common/front-end-routing/app-navigation-channel.ts
Normal file
12
src/common/front-end-routing/app-navigation-channel.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { IpcRendererNavigationEvents } from "../../renderer/navigation/events";
|
||||||
|
import type { MessageChannel } from "../utils/channel/message-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type AppNavigationChannel = MessageChannel<string>;
|
||||||
|
|
||||||
|
export const appNavigationChannel: AppNavigationChannel = {
|
||||||
|
id: IpcRendererNavigationEvents.NAVIGATE_IN_APP,
|
||||||
|
};
|
||||||
@ -1,22 +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 { IpcRendererNavigationEvents } from "../../renderer/navigation/events";
|
|
||||||
import type { MessageChannel } from "../utils/channel/message-channel-injection-token";
|
|
||||||
import { messageChannelInjectionToken } from "../utils/channel/message-channel-injection-token";
|
|
||||||
|
|
||||||
export type ClusterFrameNavigationChannel = MessageChannel<string>;
|
|
||||||
|
|
||||||
const clusterFrameNavigationChannelInjectable = getInjectable({
|
|
||||||
id: "cluster-frame-navigation-channel",
|
|
||||||
|
|
||||||
instantiate: (): ClusterFrameNavigationChannel => ({
|
|
||||||
id: IpcRendererNavigationEvents.NAVIGATE_IN_CLUSTER,
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: messageChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default clusterFrameNavigationChannelInjectable;
|
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { IpcRendererNavigationEvents } from "../../renderer/navigation/events";
|
||||||
|
import type { MessageChannel } from "../utils/channel/message-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type ClusterFrameNavigationChannel = MessageChannel<string>;
|
||||||
|
|
||||||
|
export const clusterFrameNavigationChannel: ClusterFrameNavigationChannel = {
|
||||||
|
id: IpcRendererNavigationEvents.NAVIGATE_IN_CLUSTER,
|
||||||
|
};
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* 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 isAllowedResourceInjectable from "../../../../../utils/is-allowed-resource.injectable";
|
||||||
|
import { frontEndRouteInjectionToken } from "../../../../front-end-route-injection-token";
|
||||||
|
|
||||||
|
const leasesRouteInjectable = getInjectable({
|
||||||
|
id: "leases",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const isAllowedResource = di.inject(isAllowedResourceInjectable, "leases");
|
||||||
|
|
||||||
|
return {
|
||||||
|
path: "/leases",
|
||||||
|
clusterFrame: true,
|
||||||
|
isEnabled: isAllowedResource,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: frontEndRouteInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default leasesRouteInjectable;
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* 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 leasesRouteInjectable from "./leases-route.injectable";
|
||||||
|
import { navigateToRouteInjectionToken } from "../../../../navigate-to-route-injection-token";
|
||||||
|
|
||||||
|
const navigateToLeasesInjectable = getInjectable({
|
||||||
|
id: "navigate-to-leases",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const navigateToRoute = di.inject(navigateToRouteInjectionToken);
|
||||||
|
const route = di.inject(leasesRouteInjectable);
|
||||||
|
|
||||||
|
return () => navigateToRoute(route);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default navigateToLeasesInjectable;
|
||||||
@ -5,22 +5,33 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { ExecFileOptions } from "child_process";
|
import type { ExecFileOptions } from "child_process";
|
||||||
import { execFile } from "child_process";
|
import { execFile } from "child_process";
|
||||||
import { promisify } from "util";
|
import type { AsyncResult } from "../utils/async-result";
|
||||||
|
|
||||||
export type ExecFile = (filePath: string, args: string[], options: ExecFileOptions) => Promise<string>;
|
export interface ExecFile {
|
||||||
|
(filePath: string, args: string[], options: ExecFileOptions): Promise<AsyncResult<string, { stderr: string; error: Error }>>;
|
||||||
|
}
|
||||||
|
|
||||||
const execFileInjectable = getInjectable({
|
const execFileInjectable = getInjectable({
|
||||||
id: "exec-file",
|
id: "exec-file",
|
||||||
|
|
||||||
instantiate: (): ExecFile => {
|
instantiate: (): ExecFile => (filePath, args, options) => new Promise((resolve) => {
|
||||||
const asyncExecFile = promisify(execFile);
|
execFile(filePath, args, options, (error, stdout, stderr) => {
|
||||||
|
if (error) {
|
||||||
return async (filePath, args, options) => {
|
resolve({
|
||||||
const result = await asyncExecFile(filePath, args, options);
|
callWasSuccessful: false,
|
||||||
|
error: {
|
||||||
return result.stdout;
|
error,
|
||||||
};
|
stderr,
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve({
|
||||||
|
callWasSuccessful: true,
|
||||||
|
response: stdout,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,22 +2,12 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
|
||||||
import type { HelmRepo } from "./helm-repo";
|
import type { HelmRepo } from "./helm-repo";
|
||||||
import type { RequestChannel } from "../utils/channel/request-channel-injection-token";
|
|
||||||
import { requestChannelInjectionToken } from "../utils/channel/request-channel-injection-token";
|
|
||||||
import type { AsyncResult } from "../utils/async-result";
|
import type { AsyncResult } from "../utils/async-result";
|
||||||
|
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
export type AddHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<string>>;
|
export type AddHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<string>>;
|
||||||
|
|
||||||
const addHelmRepositoryChannelInjectable = getInjectable({
|
export const addHelmRepositoryChannel: AddHelmRepositoryChannel = {
|
||||||
id: "add-helm-repository-channel",
|
id: "add-helm-repository-channel",
|
||||||
|
};
|
||||||
instantiate: (): AddHelmRepositoryChannel => ({
|
|
||||||
id: "add-helm-repository-channel",
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: requestChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default addHelmRepositoryChannelInjectable;
|
|
||||||
@ -1,23 +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 { RequestChannel } from "../utils/channel/request-channel-injection-token";
|
|
||||||
import type { HelmRepo } from "./helm-repo";
|
|
||||||
import { requestChannelInjectionToken } from "../utils/channel/request-channel-injection-token";
|
|
||||||
import type { AsyncResult } from "../utils/async-result";
|
|
||||||
|
|
||||||
export type GetHelmRepositoriesChannel = RequestChannel<void, AsyncResult<HelmRepo[]>>;
|
|
||||||
|
|
||||||
const getActiveHelmRepositoriesChannelInjectable = getInjectable({
|
|
||||||
id: "get-active-helm-repositories-channel",
|
|
||||||
|
|
||||||
instantiate: (): GetHelmRepositoriesChannel => ({
|
|
||||||
id: "get-helm-active-list-repositories",
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: requestChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default getActiveHelmRepositoriesChannelInjectable;
|
|
||||||
13
src/common/helm/get-active-helm-repositories-channel.ts
Normal file
13
src/common/helm/get-active-helm-repositories-channel.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { HelmRepo } from "./helm-repo";
|
||||||
|
import type { AsyncResult } from "../utils/async-result";
|
||||||
|
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type GetActiveHelmRepositoriesChannel = RequestChannel<void, AsyncResult<HelmRepo[]>>;
|
||||||
|
|
||||||
|
export const getActiveHelmRepositoriesChannel: GetActiveHelmRepositoriesChannel = {
|
||||||
|
id: "get-helm-active-list-repositories",
|
||||||
|
};
|
||||||
@ -1,22 +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 { HelmRepo } from "./helm-repo";
|
|
||||||
import type { RequestChannel } from "../utils/channel/request-channel-injection-token";
|
|
||||||
import { requestChannelInjectionToken } from "../utils/channel/request-channel-injection-token";
|
|
||||||
|
|
||||||
export type RemoveHelmRepositoryChannel = RequestChannel<HelmRepo>;
|
|
||||||
|
|
||||||
const removeHelmRepositoryChannelInjectable = getInjectable({
|
|
||||||
id: "remove-helm-repository-channel",
|
|
||||||
|
|
||||||
instantiate: (): RemoveHelmRepositoryChannel => ({
|
|
||||||
id: "remove-helm-repository-channel",
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: requestChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default removeHelmRepositoryChannelInjectable;
|
|
||||||
13
src/common/helm/remove-helm-repository-channel.ts
Normal file
13
src/common/helm/remove-helm-repository-channel.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { AsyncResult } from "../utils/async-result";
|
||||||
|
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||||
|
import type { HelmRepo } from "./helm-repo";
|
||||||
|
|
||||||
|
export type RemoveHelmRepositoryChannel = RequestChannel<HelmRepo, AsyncResult<string, string>>;
|
||||||
|
|
||||||
|
export const removeHelmRepositoryChannel: RemoveHelmRepositoryChannel = {
|
||||||
|
id: "remove-helm-repository-channel",
|
||||||
|
};
|
||||||
@ -19,6 +19,7 @@ export * from "./events.api";
|
|||||||
export * from "./horizontal-pod-autoscaler.api";
|
export * from "./horizontal-pod-autoscaler.api";
|
||||||
export * from "./ingress.api";
|
export * from "./ingress.api";
|
||||||
export * from "./job.api";
|
export * from "./job.api";
|
||||||
|
export * from "./lease.api";
|
||||||
export * from "./limit-range.api";
|
export * from "./limit-range.api";
|
||||||
export * from "./namespace.api";
|
export * from "./namespace.api";
|
||||||
export * from "./network-policy.api";
|
export * from "./network-policy.api";
|
||||||
|
|||||||
22
src/common/k8s-api/endpoints/lease.api.injectable.ts
Normal file
22
src/common/k8s-api/endpoints/lease.api.injectable.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import assert from "assert";
|
||||||
|
import { storesAndApisCanBeCreatedInjectionToken } from "../stores-apis-can-be-created.token";
|
||||||
|
import { LeaseApi } from "./lease.api";
|
||||||
|
import { kubeApiInjectionToken } from "../kube-api/kube-api-injection-token";
|
||||||
|
|
||||||
|
const leaseApiInjectable = getInjectable({
|
||||||
|
id: "lease-api",
|
||||||
|
instantiate: (di) => {
|
||||||
|
assert(di.inject(storesAndApisCanBeCreatedInjectionToken), "leaseApi is only available in certain environments");
|
||||||
|
|
||||||
|
return new LeaseApi();
|
||||||
|
},
|
||||||
|
|
||||||
|
injectionToken: kubeApiInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default leaseApiInjectable;
|
||||||
56
src/common/k8s-api/endpoints/lease.api.ts
Normal file
56
src/common/k8s-api/endpoints/lease.api.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { DerivedKubeApiOptions, IgnoredKubeApiOptions } from "../kube-api";
|
||||||
|
import { KubeApi } from "../kube-api";
|
||||||
|
import type { NamespaceScopedMetadata } from "../kube-object";
|
||||||
|
import { KubeObject } from "../kube-object";
|
||||||
|
|
||||||
|
export interface LeaseSpec {
|
||||||
|
acquireTime?: string;
|
||||||
|
holderIdentity: string;
|
||||||
|
leaseDurationSeconds: number;
|
||||||
|
leaseTransitions?: number;
|
||||||
|
renewTime: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Lease extends KubeObject<
|
||||||
|
NamespaceScopedMetadata,
|
||||||
|
void,
|
||||||
|
LeaseSpec
|
||||||
|
> {
|
||||||
|
static readonly kind = "Lease";
|
||||||
|
static readonly namespaced = true;
|
||||||
|
static readonly apiBase = "/apis/coordination.k8s.io/v1/leases";
|
||||||
|
|
||||||
|
getAcquireTime(): string {
|
||||||
|
return this.spec.acquireTime || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
getHolderIdentity(): string {
|
||||||
|
return this.spec.holderIdentity;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLeaseDurationSeconds(): number {
|
||||||
|
return this.spec.leaseDurationSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
getLeaseTransitions(): number | undefined {
|
||||||
|
return this.spec.leaseTransitions;
|
||||||
|
}
|
||||||
|
|
||||||
|
getRenewTime(): string {
|
||||||
|
return this.spec.renewTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class LeaseApi extends KubeApi<Lease> {
|
||||||
|
constructor(opts: DerivedKubeApiOptions & IgnoredKubeApiOptions = {}) {
|
||||||
|
super({
|
||||||
|
...opts,
|
||||||
|
objectConstructor: Lease,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export type KubeResource =
|
export type KubeResource =
|
||||||
"namespaces" | "nodes" | "events" | "resourcequotas" | "services" | "limitranges" |
|
"namespaces" | "nodes" | "events" | "resourcequotas" | "services" | "limitranges" | "leases" |
|
||||||
"secrets" | "configmaps" | "ingresses" | "networkpolicies" | "persistentvolumeclaims" | "persistentvolumes" | "storageclasses" |
|
"secrets" | "configmaps" | "ingresses" | "networkpolicies" | "persistentvolumeclaims" | "persistentvolumes" | "storageclasses" |
|
||||||
"pods" | "daemonsets" | "deployments" | "statefulsets" | "replicasets" | "jobs" | "cronjobs" |
|
"pods" | "daemonsets" | "deployments" | "statefulsets" | "replicasets" | "jobs" | "cronjobs" |
|
||||||
"endpoints" | "customresourcedefinitions" | "horizontalpodautoscalers" | "podsecuritypolicies" | "poddisruptionbudgets" |
|
"endpoints" | "customresourcedefinitions" | "horizontalpodautoscalers" | "podsecuritypolicies" | "poddisruptionbudgets" |
|
||||||
@ -35,6 +35,7 @@ export const apiResourceRecord: Record<KubeResource, KubeApiResourceData> = {
|
|||||||
"jobs": { kind: "Job", group: "batch" },
|
"jobs": { kind: "Job", group: "batch" },
|
||||||
"namespaces": { kind: "Namespace" },
|
"namespaces": { kind: "Namespace" },
|
||||||
"limitranges": { kind: "LimitRange" },
|
"limitranges": { kind: "LimitRange" },
|
||||||
|
"leases": { kind: "Lease" },
|
||||||
"networkpolicies": { kind: "NetworkPolicy", group: "networking.k8s.io" },
|
"networkpolicies": { kind: "NetworkPolicy", group: "networking.k8s.io" },
|
||||||
"nodes": { kind: "Node" },
|
"nodes": { kind: "Node" },
|
||||||
"persistentvolumes": { kind: "PersistentVolume" },
|
"persistentvolumes": { kind: "PersistentVolume" },
|
||||||
|
|||||||
@ -1,21 +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 { MessageChannel } from "../utils/channel/message-channel-injection-token";
|
|
||||||
import { messageChannelInjectionToken } from "../utils/channel/message-channel-injection-token";
|
|
||||||
|
|
||||||
export type RootFrameRenderedChannel = MessageChannel;
|
|
||||||
|
|
||||||
const rootFrameRenderedChannelInjectable = getInjectable({
|
|
||||||
id: "root-frame-rendered-channel",
|
|
||||||
|
|
||||||
instantiate: (): RootFrameRenderedChannel => ({
|
|
||||||
id: "root-frame-rendered",
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: messageChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default rootFrameRenderedChannelInjectable;
|
|
||||||
11
src/common/root-frame/root-frame-rendered-channel.ts
Normal file
11
src/common/root-frame/root-frame-rendered-channel.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { MessageChannel } from "../utils/channel/message-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type RootFrameHasRenderedChannel = MessageChannel<void>;
|
||||||
|
|
||||||
|
export const rootFrameHasRenderedChannel: RootFrameHasRenderedChannel = {
|
||||||
|
id: "root-frame-rendered",
|
||||||
|
};
|
||||||
13
src/common/user-store/resolved-shell.injectable.ts
Normal file
13
src/common/user-store/resolved-shell.injectable.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* 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 userStoreInjectable from "./user-store.injectable";
|
||||||
|
|
||||||
|
const resolvedShellInjectable = getInjectable({
|
||||||
|
id: "resolved-shell",
|
||||||
|
instantiate: (di) => di.inject(userStoreInjectable).resolvedShell,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default resolvedShellInjectable;
|
||||||
@ -6,7 +6,8 @@
|
|||||||
// Convert object's keys to camelCase format
|
// Convert object's keys to camelCase format
|
||||||
import { camelCase } from "lodash";
|
import { camelCase } from "lodash";
|
||||||
import type { SingleOrMany } from "./types";
|
import type { SingleOrMany } from "./types";
|
||||||
import { isObject } from "./type-narrowing";
|
import { isObject, isString } from "./type-narrowing";
|
||||||
|
import * as object from "./objects";
|
||||||
|
|
||||||
export function toCamelCase<T extends Record<string, unknown>[]>(obj: T): T;
|
export function toCamelCase<T extends Record<string, unknown>[]>(obj: T): T;
|
||||||
export function toCamelCase<T extends Record<string, unknown>>(obj: T): T;
|
export function toCamelCase<T extends Record<string, unknown>>(obj: T): T;
|
||||||
@ -17,11 +18,10 @@ export function toCamelCase(obj: SingleOrMany<Record<string, unknown> | unknown>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isObject(obj)) {
|
if (isObject(obj)) {
|
||||||
return Object.fromEntries(
|
return object.fromEntries(
|
||||||
Object.entries(obj)
|
object.entries(obj)
|
||||||
.map(([key, value]) => {
|
.filter((pair): pair is [string, unknown] => isString(pair[0]))
|
||||||
return [camelCase(key), toCamelCase(value)];
|
.map(([key, value]) => [camelCase(key), isObject(value) ? toCamelCase(value) : value]),
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,31 +4,31 @@
|
|||||||
*/
|
*/
|
||||||
import type { DiContainer } from "@ogre-tools/injectable";
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { MessageToChannel } from "./message-to-channel-injection-token";
|
import type { SendMessageToChannel } from "./message-to-channel-injection-token";
|
||||||
import { messageToChannelInjectionToken } from "./message-to-channel-injection-token";
|
import { sendMessageToChannelInjectionToken } from "./message-to-channel-injection-token";
|
||||||
import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
import type { ApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
||||||
import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
import { getApplicationBuilder } from "../../../renderer/components/test-utils/get-application-builder";
|
||||||
import type { LensWindow } from "../../../main/start-main-application/lens-window/application-window/create-lens-window.injectable";
|
import type { LensWindow } from "../../../main/start-main-application/lens-window/application-window/create-lens-window.injectable";
|
||||||
|
import type { MessageChannel } from "./message-channel-listener-injection-token";
|
||||||
import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token";
|
import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token";
|
||||||
import type { MessageChannel } from "./message-channel-injection-token";
|
|
||||||
import type { RequestFromChannel } from "./request-from-channel-injection-token";
|
import type { RequestFromChannel } from "./request-from-channel-injection-token";
|
||||||
import { requestFromChannelInjectionToken } from "./request-from-channel-injection-token";
|
import { requestFromChannelInjectionToken } from "./request-from-channel-injection-token";
|
||||||
import type { RequestChannel } from "./request-channel-injection-token";
|
import type { RequestChannel } from "./request-channel-listener-injection-token";
|
||||||
import { requestChannelListenerInjectionToken } from "./request-channel-listener-injection-token";
|
|
||||||
import type { AsyncFnMock } from "@async-fn/jest";
|
import type { AsyncFnMock } from "@async-fn/jest";
|
||||||
import asyncFn from "@async-fn/jest";
|
import asyncFn from "@async-fn/jest";
|
||||||
import { getPromiseStatus } from "../../test-utils/get-promise-status";
|
import { getPromiseStatus } from "../../test-utils/get-promise-status";
|
||||||
import { runInAction } from "mobx";
|
import { runInAction } from "mobx";
|
||||||
|
import type { RequestChannelHandler } from "../../../main/utils/channel/channel-listeners/listener-tokens";
|
||||||
|
import { getRequestChannelListenerInjectable } from "../../../main/utils/channel/channel-listeners/listener-tokens";
|
||||||
|
|
||||||
type TestMessageChannel = MessageChannel<string>;
|
type TestMessageChannel = MessageChannel<string>;
|
||||||
type TestRequestChannel = RequestChannel<string, string>;
|
type TestRequestChannel = RequestChannel<string, string>;
|
||||||
|
|
||||||
describe("channel", () => {
|
describe("channel", () => {
|
||||||
describe("messaging from main to renderer, given listener for channel in a window and application has started", () => {
|
describe("messaging from main to renderer, given listener for channel in a window and application has started", () => {
|
||||||
let testMessageChannel: TestMessageChannel;
|
|
||||||
let messageListenerInWindowMock: jest.Mock;
|
let messageListenerInWindowMock: jest.Mock;
|
||||||
let mainDi: DiContainer;
|
let mainDi: DiContainer;
|
||||||
let messageToChannel: MessageToChannel;
|
let messageToChannel: SendMessageToChannel;
|
||||||
let builder: ApplicationBuilder;
|
let builder: ApplicationBuilder;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@ -39,24 +39,17 @@ describe("channel", () => {
|
|||||||
const testChannelListenerInTestWindowInjectable = getInjectable({
|
const testChannelListenerInTestWindowInjectable = getInjectable({
|
||||||
id: "test-channel-listener-in-test-window",
|
id: "test-channel-listener-in-test-window",
|
||||||
|
|
||||||
instantiate: (di) => ({
|
instantiate: () => ({
|
||||||
channel: di.inject(testMessageChannelInjectable),
|
channel: testMessageChannel,
|
||||||
handler: messageListenerInWindowMock,
|
handler: messageListenerInWindowMock,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
injectionToken: messageChannelListenerInjectionToken,
|
injectionToken: messageChannelListenerInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.beforeApplicationStart((mainDi) => {
|
|
||||||
runInAction(() => {
|
|
||||||
mainDi.register(testMessageChannelInjectable);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.beforeWindowStart((windowDi) => {
|
builder.beforeWindowStart((windowDi) => {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
windowDi.register(testChannelListenerInTestWindowInjectable);
|
windowDi.register(testChannelListenerInTestWindowInjectable);
|
||||||
windowDi.register(testMessageChannelInjectable);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -64,8 +57,7 @@ describe("channel", () => {
|
|||||||
|
|
||||||
await builder.startHidden();
|
await builder.startHidden();
|
||||||
|
|
||||||
testMessageChannel = mainDi.inject(testMessageChannelInjectable);
|
messageToChannel = mainDi.inject(sendMessageToChannelInjectionToken);
|
||||||
messageToChannel = mainDi.inject(messageToChannelInjectionToken);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("given window is started", () => {
|
describe("given window is started", () => {
|
||||||
@ -109,9 +101,8 @@ describe("channel", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("messaging from renderer to main, given listener for channel in a main and application has started", () => {
|
describe("messaging from renderer to main, given listener for channel in a main and application has started", () => {
|
||||||
let testMessageChannel: TestMessageChannel;
|
|
||||||
let messageListenerInMainMock: jest.Mock;
|
let messageListenerInMainMock: jest.Mock;
|
||||||
let messageToChannel: MessageToChannel;
|
let messageToChannel: SendMessageToChannel;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const applicationBuilder = getApplicationBuilder();
|
const applicationBuilder = getApplicationBuilder();
|
||||||
@ -121,9 +112,8 @@ describe("channel", () => {
|
|||||||
const testChannelListenerInMainInjectable = getInjectable({
|
const testChannelListenerInMainInjectable = getInjectable({
|
||||||
id: "test-channel-listener-in-main",
|
id: "test-channel-listener-in-main",
|
||||||
|
|
||||||
instantiate: (di) => ({
|
instantiate: () => ({
|
||||||
channel: di.inject(testMessageChannelInjectable),
|
channel: testMessageChannel,
|
||||||
|
|
||||||
handler: messageListenerInMainMock,
|
handler: messageListenerInMainMock,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -133,13 +123,6 @@ describe("channel", () => {
|
|||||||
applicationBuilder.beforeApplicationStart((mainDi) => {
|
applicationBuilder.beforeApplicationStart((mainDi) => {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
mainDi.register(testChannelListenerInMainInjectable);
|
mainDi.register(testChannelListenerInMainInjectable);
|
||||||
mainDi.register(testMessageChannelInjectable);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
applicationBuilder.beforeWindowStart((windowDi) => {
|
|
||||||
runInAction(() => {
|
|
||||||
windowDi.register(testMessageChannelInjectable);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -147,8 +130,7 @@ describe("channel", () => {
|
|||||||
|
|
||||||
const windowDi = applicationBuilder.applicationWindow.only.di;
|
const windowDi = applicationBuilder.applicationWindow.only.di;
|
||||||
|
|
||||||
testMessageChannel = windowDi.inject(testMessageChannelInjectable);
|
messageToChannel = windowDi.inject(sendMessageToChannelInjectionToken);
|
||||||
messageToChannel = windowDi.inject(messageToChannelInjectionToken);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("when sending message, triggers listener in main", () => {
|
it("when sending message, triggers listener in main", () => {
|
||||||
@ -159,8 +141,7 @@ describe("channel", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("requesting from main in renderer, given listener for channel in a main and application has started", () => {
|
describe("requesting from main in renderer, given listener for channel in a main and application has started", () => {
|
||||||
let testRequestChannel: TestRequestChannel;
|
let requestListenerInMainMock: AsyncFnMock<RequestChannelHandler<TestRequestChannel>>;
|
||||||
let requestListenerInMainMock: AsyncFnMock<(arg: string) => string>;
|
|
||||||
let requestFromChannel: RequestFromChannel;
|
let requestFromChannel: RequestFromChannel;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@ -168,28 +149,14 @@ describe("channel", () => {
|
|||||||
|
|
||||||
requestListenerInMainMock = asyncFn();
|
requestListenerInMainMock = asyncFn();
|
||||||
|
|
||||||
const testChannelListenerInMainInjectable = getInjectable({
|
const testChannelListenerInMainInjectable = getRequestChannelListenerInjectable({
|
||||||
id: "test-channel-listener-in-main",
|
channel: testRequestChannel,
|
||||||
|
handler: () => requestListenerInMainMock,
|
||||||
instantiate: (di) => ({
|
|
||||||
channel: di.inject(testRequestChannelInjectable),
|
|
||||||
|
|
||||||
handler: requestListenerInMainMock,
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: requestChannelListenerInjectionToken,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
applicationBuilder.beforeApplicationStart((mainDi) => {
|
applicationBuilder.beforeApplicationStart((mainDi) => {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
mainDi.register(testChannelListenerInMainInjectable);
|
mainDi.register(testChannelListenerInMainInjectable);
|
||||||
mainDi.register(testRequestChannelInjectable);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
applicationBuilder.beforeWindowStart((windowDi) => {
|
|
||||||
runInAction(() => {
|
|
||||||
windowDi.register(testRequestChannelInjectable);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -197,8 +164,6 @@ describe("channel", () => {
|
|||||||
|
|
||||||
const windowDi = applicationBuilder.applicationWindow.only.di;
|
const windowDi = applicationBuilder.applicationWindow.only.di;
|
||||||
|
|
||||||
testRequestChannel = windowDi.inject(testRequestChannelInjectable);
|
|
||||||
|
|
||||||
requestFromChannel = windowDi.inject(
|
requestFromChannel = windowDi.inject(
|
||||||
requestFromChannelInjectionToken,
|
requestFromChannelInjectionToken,
|
||||||
);
|
);
|
||||||
@ -230,21 +195,37 @@ describe("channel", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("when registering multiple handlers for the same channel, throws", async () => {
|
||||||
|
const applicationBuilder = getApplicationBuilder();
|
||||||
|
|
||||||
|
const testChannelListenerInMainInjectable = getRequestChannelListenerInjectable({
|
||||||
|
channel: testRequestChannel,
|
||||||
|
handler: () => () => "some-value",
|
||||||
|
});
|
||||||
|
const testChannelListenerInMain2Injectable = getRequestChannelListenerInjectable({
|
||||||
|
channel: testRequestChannel,
|
||||||
|
handler: () => () => "some-other-value",
|
||||||
|
});
|
||||||
|
|
||||||
|
testChannelListenerInMain2Injectable.id += "2";
|
||||||
|
|
||||||
|
applicationBuilder.beforeApplicationStart((mainDi) => {
|
||||||
|
runInAction(() => {
|
||||||
|
mainDi.register(testChannelListenerInMainInjectable);
|
||||||
|
mainDi.register(testChannelListenerInMain2Injectable);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(applicationBuilder.render()).rejects.toThrow('Tried to register a multiple channel handlers for "some-request-channel-id", only one handler is supported for a request channel.');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const testMessageChannelInjectable = getInjectable({
|
const testMessageChannel: TestMessageChannel = {
|
||||||
id: "some-message-test-channel",
|
id: "some-message-channel-id",
|
||||||
|
};
|
||||||
|
|
||||||
instantiate: (): TestMessageChannel => ({
|
const testRequestChannel: TestRequestChannel = {
|
||||||
id: "some-message-channel-id",
|
id: "some-request-channel-id",
|
||||||
}),
|
};
|
||||||
});
|
|
||||||
|
|
||||||
const testRequestChannelInjectable = getInjectable({
|
|
||||||
id: "some-request-test-channel",
|
|
||||||
|
|
||||||
instantiate: (): TestRequestChannel => ({
|
|
||||||
id: "some-request-channel-id",
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|||||||
@ -3,14 +3,11 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { MessageChannel } from "./message-channel-injection-token";
|
import type { Disposer } from "../disposer";
|
||||||
import type { MessageChannelListener } from "./message-channel-listener-injection-token";
|
import type { MessageChannel, MessageChannelListener } from "./message-channel-listener-injection-token";
|
||||||
|
|
||||||
export type EnlistMessageChannelListener = <
|
export type EnlistMessageChannelListener = (listener: MessageChannelListener<MessageChannel<unknown>>) => Disposer;
|
||||||
TChannel extends MessageChannel<any>,
|
|
||||||
>(listener: MessageChannelListener<TChannel>) => () => void;
|
|
||||||
|
|
||||||
export const enlistMessageChannelListenerInjectionToken =
|
export const enlistMessageChannelListenerInjectionToken = getInjectionToken<EnlistMessageChannelListener>({
|
||||||
getInjectionToken<EnlistMessageChannelListener>({
|
id: "enlist-message-channel-listener",
|
||||||
id: "enlist-message-channel-listener",
|
});
|
||||||
});
|
|
||||||
|
|||||||
@ -1,16 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
|
||||||
import type { RequestChannel } from "./request-channel-injection-token";
|
|
||||||
import type { RequestChannelListener } from "./request-channel-listener-injection-token";
|
|
||||||
|
|
||||||
export type EnlistRequestChannelListener = <
|
|
||||||
TChannel extends RequestChannel<any, any>,
|
|
||||||
>(listener: RequestChannelListener<TChannel>) => () => void;
|
|
||||||
|
|
||||||
export const enlistRequestChannelListenerInjectionToken =
|
|
||||||
getInjectionToken<EnlistRequestChannelListener>({
|
|
||||||
id: "enlist-request-channel-listener",
|
|
||||||
});
|
|
||||||
@ -1,32 +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 { getStartableStoppable } from "../get-startable-stoppable";
|
|
||||||
import { disposer } from "../index";
|
|
||||||
import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token";
|
|
||||||
import { requestChannelListenerInjectionToken } from "./request-channel-listener-injection-token";
|
|
||||||
import { enlistMessageChannelListenerInjectionToken } from "./enlist-message-channel-listener-injection-token";
|
|
||||||
import { enlistRequestChannelListenerInjectionToken } from "./enlist-request-channel-listener-injection-token";
|
|
||||||
|
|
||||||
const listeningOfChannelsInjectable = getInjectable({
|
|
||||||
id: "listening-of-channels",
|
|
||||||
|
|
||||||
instantiate: (di) => {
|
|
||||||
const enlistMessageChannelListener = di.inject(enlistMessageChannelListenerInjectionToken);
|
|
||||||
const enlistRequestChannelListener = di.inject(enlistRequestChannelListenerInjectionToken);
|
|
||||||
const messageChannelListeners = di.injectMany(messageChannelListenerInjectionToken);
|
|
||||||
const requestChannelListeners = di.injectMany(requestChannelListenerInjectionToken);
|
|
||||||
|
|
||||||
return getStartableStoppable("listening-of-channels", () => {
|
|
||||||
const messageChannelDisposers = messageChannelListeners.map(enlistMessageChannelListener);
|
|
||||||
const requestChannelDisposers = requestChannelListeners.map(enlistRequestChannelListener);
|
|
||||||
|
|
||||||
return disposer(...messageChannelDisposers, ...requestChannelDisposers);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export default listeningOfChannelsInjectable;
|
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* 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 { getStartableStoppable } from "../get-startable-stoppable";
|
||||||
|
import { disposer } from "../index";
|
||||||
|
import { messageChannelListenerInjectionToken } from "./message-channel-listener-injection-token";
|
||||||
|
import { enlistMessageChannelListenerInjectionToken } from "./enlist-message-channel-listener-injection-token";
|
||||||
|
|
||||||
|
const listeningOnMessageChannelsInjectable = getInjectable({
|
||||||
|
id: "listening-on-message-channels",
|
||||||
|
|
||||||
|
instantiate: (di) => {
|
||||||
|
const enlistMessageChannelListener = di.inject(enlistMessageChannelListenerInjectionToken);
|
||||||
|
const messageChannelListeners = di.injectMany(messageChannelListenerInjectionToken);
|
||||||
|
|
||||||
|
return getStartableStoppable("listening-on-channels", () => (
|
||||||
|
disposer(messageChannelListeners.map(enlistMessageChannelListener))
|
||||||
|
));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export default listeningOnMessageChannelsInjectable;
|
||||||
@ -1,16 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
|
||||||
import type { JsonValue } from "type-fest";
|
|
||||||
|
|
||||||
export interface MessageChannel<Message extends JsonValue | void = void> {
|
|
||||||
id: string;
|
|
||||||
_messageSignature?: Message;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const messageChannelInjectionToken = getInjectionToken<MessageChannel<any>>({
|
|
||||||
id: "message-channel",
|
|
||||||
});
|
|
||||||
@ -2,17 +2,50 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import type { DiContainerForInjection } from "@ogre-tools/injectable";
|
||||||
import type { SetRequired } from "type-fest";
|
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { MessageChannel } from "./message-channel-injection-token";
|
|
||||||
|
|
||||||
export interface MessageChannelListener<TChannel extends MessageChannel<any>> {
|
export interface MessageChannel<Message> {
|
||||||
channel: TChannel;
|
id: string;
|
||||||
handler: (value: SetRequired<TChannel, "_messageSignature">["_messageSignature"]) => void;
|
_messageSignature?: Message; // only used to mark `Message` as used
|
||||||
}
|
}
|
||||||
|
|
||||||
export const messageChannelListenerInjectionToken = getInjectionToken<MessageChannelListener<MessageChannel<any>>>(
|
export type MessageChannelHandler<Channel> = Channel extends MessageChannel<infer Message>
|
||||||
|
? (message: Message) => void
|
||||||
|
: never;
|
||||||
|
|
||||||
|
export interface MessageChannelListener<Channel> {
|
||||||
|
channel: Channel;
|
||||||
|
handler: MessageChannelHandler<Channel>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const messageChannelListenerInjectionToken = getInjectionToken<MessageChannelListener<MessageChannel<unknown>>>(
|
||||||
{
|
{
|
||||||
id: "message-channel-listener",
|
id: "message-channel-listener",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export interface GetMessageChannelListenerInfo<
|
||||||
|
Channel extends MessageChannel<Message>,
|
||||||
|
Message,
|
||||||
|
> {
|
||||||
|
id: string;
|
||||||
|
channel: Channel;
|
||||||
|
handler: (di: DiContainerForInjection) => MessageChannelHandler<Channel>;
|
||||||
|
causesSideEffects?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMessageChannelListenerInjectable<
|
||||||
|
Channel extends MessageChannel<Message>,
|
||||||
|
Message,
|
||||||
|
>(info: GetMessageChannelListenerInfo<Channel, Message>) {
|
||||||
|
return getInjectable({
|
||||||
|
id: `${info.channel.id}-listener-${info.id}`,
|
||||||
|
instantiate: (di) => ({
|
||||||
|
channel: info.channel,
|
||||||
|
handler: info.handler(di),
|
||||||
|
}),
|
||||||
|
injectionToken: messageChannelListenerInjectionToken,
|
||||||
|
causesSideEffects: info.causesSideEffects,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -3,21 +3,13 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { SetRequired } from "type-fest";
|
import type { MessageChannel } from "./message-channel-listener-injection-token";
|
||||||
import type { MessageChannel } from "./message-channel-injection-token";
|
|
||||||
|
|
||||||
export interface MessageToChannel {
|
export interface SendMessageToChannel {
|
||||||
<TChannel extends MessageChannel<TMessage>, TMessage extends void>(
|
(channel: MessageChannel<void>): void;
|
||||||
channel: TChannel,
|
<Message>(channel: MessageChannel<Message>, message: Message): void;
|
||||||
): void;
|
|
||||||
|
|
||||||
<TChannel extends MessageChannel<any>>(
|
|
||||||
channel: TChannel,
|
|
||||||
message: SetRequired<TChannel, "_messageSignature">["_messageSignature"],
|
|
||||||
): void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const messageToChannelInjectionToken =
|
export const sendMessageToChannelInjectionToken = getInjectionToken<SendMessageToChannel>({
|
||||||
getInjectionToken<MessageToChannel>({
|
id: "send-message-to-message-channel",
|
||||||
id: "message-to-message-channel",
|
});
|
||||||
});
|
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
|
||||||
import type { JsonValue } from "type-fest";
|
|
||||||
|
|
||||||
export interface RequestChannel<
|
|
||||||
Request extends JsonValue | void = void,
|
|
||||||
Response extends JsonValue | void = void,
|
|
||||||
> {
|
|
||||||
id: string;
|
|
||||||
_requestSignature?: Request;
|
|
||||||
_responseSignature?: Response;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const requestChannelInjectionToken = getInjectionToken<RequestChannel<any, any>>({
|
|
||||||
id: "request-channel",
|
|
||||||
});
|
|
||||||
@ -2,24 +2,9 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
|
||||||
import type { SetRequired } from "type-fest";
|
|
||||||
import type { RequestChannel } from "./request-channel-injection-token";
|
|
||||||
|
|
||||||
export interface RequestChannelListener<TChannel extends RequestChannel<any, any>> {
|
export interface RequestChannel<Request, Response> {
|
||||||
channel: TChannel;
|
id: string;
|
||||||
|
_requestSignature?: Request; // used only to mark `Request` as "used"
|
||||||
handler: (
|
_responseSignature?: Response; // used only to mark `Response` as "used"
|
||||||
request: SetRequired<TChannel, "_requestSignature">["_requestSignature"]
|
|
||||||
) =>
|
|
||||||
| SetRequired<TChannel, "_responseSignature">["_responseSignature"]
|
|
||||||
| Promise<
|
|
||||||
SetRequired<TChannel, "_responseSignature">["_responseSignature"]
|
|
||||||
>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const requestChannelListenerInjectionToken = getInjectionToken<RequestChannelListener<RequestChannel<any, any>>>(
|
|
||||||
{
|
|
||||||
id: "request-channel-listener",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|||||||
@ -3,19 +3,13 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectionToken } from "@ogre-tools/injectable";
|
import { getInjectionToken } from "@ogre-tools/injectable";
|
||||||
import type { SetRequired } from "type-fest";
|
import type { RequestChannel } from "./request-channel-listener-injection-token";
|
||||||
import type { RequestChannel } from "./request-channel-injection-token";
|
|
||||||
|
|
||||||
export type RequestFromChannel = <
|
export interface RequestFromChannel {
|
||||||
TChannel extends RequestChannel<any, any>,
|
<Request, Response>(channel: RequestChannel<Request, Response>, request: Request): Promise<Response>;
|
||||||
>(
|
<Response>(channel: RequestChannel<void, Response>): Promise<Response>;
|
||||||
channel: TChannel,
|
}
|
||||||
...request: TChannel["_requestSignature"] extends void
|
|
||||||
? []
|
|
||||||
: [SetRequired<TChannel, "_requestSignature">["_requestSignature"]]
|
|
||||||
) => Promise<SetRequired<TChannel, "_responseSignature">["_responseSignature"]>;
|
|
||||||
|
|
||||||
export const requestFromChannelInjectionToken =
|
export const requestFromChannelInjectionToken = getInjectionToken<RequestFromChannel>({
|
||||||
getInjectionToken<RequestFromChannel>({
|
id: "request-from-request-channel",
|
||||||
id: "request-from-request-channel",
|
});
|
||||||
});
|
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { SingleOrMany } from "./types";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface Disposer {
|
export interface Disposer {
|
||||||
@ -17,9 +19,9 @@ export interface ExtendableDisposer extends Disposer {
|
|||||||
push(...vals: (Disposer | ExtendableDisposer | Disposable)[]): void;
|
push(...vals: (Disposer | ExtendableDisposer | Disposable)[]): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function disposer(...items: (Disposer | Disposable | undefined | null)[]): ExtendableDisposer {
|
export function disposer(...items: SingleOrMany<Disposer | Disposable | undefined | null>[]): ExtendableDisposer {
|
||||||
return Object.assign(() => {
|
return Object.assign(() => {
|
||||||
for (const item of items) {
|
for (const item of items.flat()) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,53 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import request from "request";
|
|
||||||
import type { JsonValue } from "type-fest";
|
|
||||||
import { parse } from "./json";
|
|
||||||
|
|
||||||
export interface DownloadFileOptions {
|
|
||||||
url: string;
|
|
||||||
gzip?: boolean;
|
|
||||||
timeout?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DownloadFileTicket<T> {
|
|
||||||
url: string;
|
|
||||||
promise: Promise<T>;
|
|
||||||
cancel(): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function downloadFile({ url, timeout, gzip = true }: DownloadFileOptions): DownloadFileTicket<Buffer> {
|
|
||||||
const fileChunks: Buffer[] = [];
|
|
||||||
const req = request(url, { gzip, timeout });
|
|
||||||
const promise: Promise<Buffer> = new Promise((resolve, reject) => {
|
|
||||||
req.on("data", (chunk: Buffer) => {
|
|
||||||
fileChunks.push(chunk);
|
|
||||||
});
|
|
||||||
req.once("error", err => {
|
|
||||||
reject({ url, err });
|
|
||||||
});
|
|
||||||
req.once("complete", () => {
|
|
||||||
resolve(Buffer.concat(fileChunks));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
url,
|
|
||||||
promise,
|
|
||||||
cancel() {
|
|
||||||
req.abort();
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function downloadJson(args: DownloadFileOptions): DownloadFileTicket<JsonValue> {
|
|
||||||
const { promise, ...rest } = downloadFile(args);
|
|
||||||
|
|
||||||
return {
|
|
||||||
promise: promise.then(res => parse(res.toString())),
|
|
||||||
...rest,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -14,7 +14,6 @@ export * from "./convertMemory";
|
|||||||
export * from "./debouncePromise";
|
export * from "./debouncePromise";
|
||||||
export * from "./delay";
|
export * from "./delay";
|
||||||
export * from "./disposer";
|
export * from "./disposer";
|
||||||
export * from "./downloadFile";
|
|
||||||
export * from "./escapeRegExp";
|
export * from "./escapeRegExp";
|
||||||
export * from "./formatDuration";
|
export * from "./formatDuration";
|
||||||
export * from "./getRandId";
|
export * from "./getRandId";
|
||||||
|
|||||||
@ -1,21 +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 { RequestChannel } from "../channel/request-channel-injection-token";
|
|
||||||
import { requestChannelInjectionToken } from "../channel/request-channel-injection-token";
|
|
||||||
|
|
||||||
export type ResolveSystemProxyChannel = RequestChannel<string, string>;
|
|
||||||
|
|
||||||
const resolveSystemProxyChannelInjectable = getInjectable({
|
|
||||||
id: "resolve-system-proxy-channel",
|
|
||||||
|
|
||||||
instantiate: (): ResolveSystemProxyChannel => ({
|
|
||||||
id: "resolve-system-proxy-channel",
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: requestChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default resolveSystemProxyChannelInjectable;
|
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { RequestChannel } from "../channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type ResolveSystemProxyChannel = RequestChannel<string, string>;
|
||||||
|
|
||||||
|
export const resolveSystemProxyChannel: ResolveSystemProxyChannel = {
|
||||||
|
id: "resolve-system-proxy-channel",
|
||||||
|
};
|
||||||
15
src/common/utils/sync-box/channel-listener.injectable.ts
Normal file
15
src/common/utils/sync-box/channel-listener.injectable.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import { syncBoxChannel } from "./channels";
|
||||||
|
import { getMessageChannelListenerInjectable } from "../channel/message-channel-listener-injection-token";
|
||||||
|
import syncBoxStateInjectable from "./sync-box-state.injectable";
|
||||||
|
|
||||||
|
const syncBoxChannelListenerInjectable = getMessageChannelListenerInjectable({
|
||||||
|
id: "init",
|
||||||
|
channel: syncBoxChannel,
|
||||||
|
handler: (di) => ({ id, value }) => di.inject(syncBoxStateInjectable, id).set(value),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default syncBoxChannelListenerInjectable;
|
||||||
21
src/common/utils/sync-box/channels.ts
Normal file
21
src/common/utils/sync-box/channels.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { MessageChannel } from "../channel/message-channel-listener-injection-token";
|
||||||
|
import type { RequestChannel } from "../channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type SyncBoxChannel = MessageChannel<{ id: string; value: any }>;
|
||||||
|
|
||||||
|
export const syncBoxChannel: SyncBoxChannel = {
|
||||||
|
id: "sync-box-channel",
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SyncBoxInitialValueChannel = RequestChannel<
|
||||||
|
void,
|
||||||
|
{ id: string; value: any }[]
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const syncBoxInitialValueChannel: SyncBoxInitialValueChannel = {
|
||||||
|
id: "sync-box-initial-value-channel",
|
||||||
|
};
|
||||||
@ -5,17 +5,17 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { IObservableValue } from "mobx";
|
import type { IObservableValue } from "mobx";
|
||||||
import { computed } from "mobx";
|
import { computed } from "mobx";
|
||||||
import syncBoxChannelInjectable from "./sync-box-channel.injectable";
|
import { syncBoxChannel } from "./channels";
|
||||||
import { messageToChannelInjectionToken } from "../channel/message-to-channel-injection-token";
|
import { sendMessageToChannelInjectionToken } from "../channel/message-to-channel-injection-token";
|
||||||
import syncBoxStateInjectable from "./sync-box-state.injectable";
|
import syncBoxStateInjectable from "./sync-box-state.injectable";
|
||||||
import type { SyncBox } from "./sync-box-injection-token";
|
import type { SyncBox } from "./sync-box-injection-token";
|
||||||
|
import { toJS } from "../toJS";
|
||||||
|
|
||||||
const createSyncBoxInjectable = getInjectable({
|
const createSyncBoxInjectable = getInjectable({
|
||||||
id: "create-sync-box",
|
id: "create-sync-box",
|
||||||
|
|
||||||
instantiate: (di) => {
|
instantiate: (di) => {
|
||||||
const syncBoxChannel = di.inject(syncBoxChannelInjectable);
|
const messageToChannel = di.inject(sendMessageToChannelInjectionToken);
|
||||||
const messageToChannel = di.inject(messageToChannelInjectionToken);
|
|
||||||
const getSyncBoxState = (id: string) => di.inject(syncBoxStateInjectable, id);
|
const getSyncBoxState = (id: string) => di.inject(syncBoxStateInjectable, id);
|
||||||
|
|
||||||
return <Value>(id: string, initialValue: Value): SyncBox<Value> => {
|
return <Value>(id: string, initialValue: Value): SyncBox<Value> => {
|
||||||
@ -26,7 +26,7 @@ const createSyncBoxInjectable = getInjectable({
|
|||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
|
|
||||||
value: computed(() => state.get()),
|
value: computed(() => toJS(state.get())),
|
||||||
|
|
||||||
set: (value) => {
|
set: (value) => {
|
||||||
state.set(value);
|
state.set(value);
|
||||||
|
|||||||
19
src/common/utils/sync-box/handler.injectable.ts
Normal file
19
src/common/utils/sync-box/handler.injectable.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* 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 { MessageChannelHandler } from "../channel/message-channel-listener-injection-token";
|
||||||
|
import type { SyncBoxChannel } from "./channels";
|
||||||
|
import syncBoxStateInjectable from "./sync-box-state.injectable";
|
||||||
|
|
||||||
|
const syncBoxChannelHandlerInjectable = getInjectable({
|
||||||
|
id: "sync-box-channel-handler",
|
||||||
|
instantiate: (di): MessageChannelHandler<SyncBoxChannel> => {
|
||||||
|
const getSyncBoxState = (id: string) => di.inject(syncBoxStateInjectable, id);
|
||||||
|
|
||||||
|
return ({ id, value }) => getSyncBoxState(id)?.set(value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default syncBoxChannelHandlerInjectable;
|
||||||
@ -1,35 +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 { SyncBoxChannel } from "./sync-box-channel.injectable";
|
|
||||||
import syncBoxChannelInjectable from "./sync-box-channel.injectable";
|
|
||||||
import syncBoxStateInjectable from "./sync-box-state.injectable";
|
|
||||||
import type { MessageChannelListener } from "../channel/message-channel-listener-injection-token";
|
|
||||||
import { messageChannelListenerInjectionToken } from "../channel/message-channel-listener-injection-token";
|
|
||||||
|
|
||||||
const syncBoxChannelListenerInjectable = getInjectable({
|
|
||||||
id: "sync-box-channel-listener",
|
|
||||||
|
|
||||||
instantiate: (di): MessageChannelListener<SyncBoxChannel> => {
|
|
||||||
const getSyncBoxState = (id: string) => di.inject(syncBoxStateInjectable, id);
|
|
||||||
const channel = di.inject(syncBoxChannelInjectable);
|
|
||||||
|
|
||||||
return {
|
|
||||||
channel,
|
|
||||||
|
|
||||||
handler: ({ id, value }) => {
|
|
||||||
const target = getSyncBoxState(id);
|
|
||||||
|
|
||||||
if (target) {
|
|
||||||
target.set(value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
injectionToken: messageChannelListenerInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default syncBoxChannelListenerInjectable;
|
|
||||||
@ -1,21 +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 { MessageChannel } from "../channel/message-channel-injection-token";
|
|
||||||
import { messageChannelInjectionToken } from "../channel/message-channel-injection-token";
|
|
||||||
|
|
||||||
export type SyncBoxChannel = MessageChannel<{ id: string; value: any }>;
|
|
||||||
|
|
||||||
const syncBoxChannelInjectable = getInjectable({
|
|
||||||
id: "sync-box-channel",
|
|
||||||
|
|
||||||
instantiate: (): SyncBoxChannel => ({
|
|
||||||
id: "sync-box-channel",
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: messageChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default syncBoxChannelInjectable;
|
|
||||||
@ -1,24 +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 { RequestChannel } from "../channel/request-channel-injection-token";
|
|
||||||
import { requestChannelInjectionToken } from "../channel/request-channel-injection-token";
|
|
||||||
|
|
||||||
export type SyncBoxInitialValueChannel = RequestChannel<
|
|
||||||
void,
|
|
||||||
{ id: string; value: any }[]
|
|
||||||
>;
|
|
||||||
|
|
||||||
const syncBoxInitialValueChannelInjectable = getInjectable({
|
|
||||||
id: "sync-box-initial-value-channel",
|
|
||||||
|
|
||||||
instantiate: (): SyncBoxInitialValueChannel => ({
|
|
||||||
id: "sync-box-initial-value-channel",
|
|
||||||
}),
|
|
||||||
|
|
||||||
injectionToken: requestChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default syncBoxInitialValueChannelInjectable;
|
|
||||||
@ -5,7 +5,6 @@
|
|||||||
|
|
||||||
// Helper for working with tarball files (.tar, .tgz)
|
// Helper for working with tarball files (.tar, .tgz)
|
||||||
// Docs: https://github.com/npm/node-tar
|
// Docs: https://github.com/npm/node-tar
|
||||||
import type { FileStat } from "tar";
|
|
||||||
import tar from "tar";
|
import tar from "tar";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { parse } from "./json";
|
import { parse } from "./json";
|
||||||
@ -35,7 +34,7 @@ export function readFileFromTar<ParseJson extends boolean>({ tarPath, filePath,
|
|||||||
file: tarPath,
|
file: tarPath,
|
||||||
filter: entryPath => path.normalize(entryPath) === filePath,
|
filter: entryPath => path.normalize(entryPath) === filePath,
|
||||||
sync: true,
|
sync: true,
|
||||||
onentry(entry: FileStat) {
|
onentry(entry) {
|
||||||
entry.on("data", chunk => {
|
entry.on("data", chunk => {
|
||||||
fileChunks.push(chunk);
|
fileChunks.push(chunk);
|
||||||
});
|
});
|
||||||
@ -63,7 +62,7 @@ export async function listTarEntries(filePath: string): Promise<string[]> {
|
|||||||
await tar.list({
|
await tar.list({
|
||||||
file: filePath,
|
file: filePath,
|
||||||
onentry: (entry) => {
|
onentry: (entry) => {
|
||||||
entries.push(path.normalize(entry.path as unknown as string));
|
entries.push(path.normalize(entry.path));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { pipeline } from "@ogre-tools/fp";
|
|
||||||
import { defaultTo } from "lodash/fp";
|
|
||||||
import { withErrorSuppression } from "./with-error-suppression/with-error-suppression";
|
|
||||||
|
|
||||||
export const tentativeParseJson = (toBeParsed: any) => pipeline(
|
|
||||||
toBeParsed,
|
|
||||||
withErrorSuppression(JSON.parse),
|
|
||||||
defaultTo(toBeParsed),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
|
||||||
*/
|
|
||||||
import { pipeline } from "@ogre-tools/fp";
|
|
||||||
import { defaultTo } from "lodash/fp";
|
|
||||||
import { withErrorSuppression } from "./with-error-suppression/with-error-suppression";
|
|
||||||
|
|
||||||
export const tentativeStringifyJson = (toBeParsed: any) => pipeline(
|
|
||||||
toBeParsed,
|
|
||||||
withErrorSuppression(JSON.stringify),
|
|
||||||
defaultTo(toBeParsed),
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ export function isBoolean(val: unknown): val is boolean {
|
|||||||
* checks if val is of type object and isn't null
|
* checks if val is of type object and isn't null
|
||||||
* @param val the value to be checked
|
* @param val the value to be checked
|
||||||
*/
|
*/
|
||||||
export function isObject(val: unknown): val is object {
|
export function isObject(val: unknown): val is Record<string | symbol | number, unknown> {
|
||||||
return typeof val === "object" && val !== null;
|
return typeof val === "object" && val !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -123,7 +123,7 @@ export const apiKubePrefix = "/api-kube"; // k8s cluster apis
|
|||||||
// Links
|
// Links
|
||||||
export const issuesTrackerUrl = "https://github.com/lensapp/lens/issues" as string;
|
export const issuesTrackerUrl = "https://github.com/lensapp/lens/issues" as string;
|
||||||
export const slackUrl = "https://join.slack.com/t/k8slens/shared_invite/zt-wcl8jq3k-68R5Wcmk1o95MLBE5igUDQ" as string;
|
export const slackUrl = "https://join.slack.com/t/k8slens/shared_invite/zt-wcl8jq3k-68R5Wcmk1o95MLBE5igUDQ" as string;
|
||||||
export const supportUrl = "https://docs.k8slens.dev/latest/support/" as string;
|
export const supportUrl = "https://docs.k8slens.dev/support/" as string;
|
||||||
|
|
||||||
export const lensWebsiteWeblinkId = "lens-website-link";
|
export const lensWebsiteWeblinkId = "lens-website-link";
|
||||||
export const lensDocumentationWeblinkId = "lens-documentation-link";
|
export const lensDocumentationWeblinkId = "lens-documentation-link";
|
||||||
@ -132,4 +132,4 @@ export const lensTwitterWeblinkId = "lens-twitter-link";
|
|||||||
export const lensBlogWeblinkId = "lens-blog-link";
|
export const lensBlogWeblinkId = "lens-blog-link";
|
||||||
export const kubernetesDocumentationWeblinkId = "kubernetes-documentation-link";
|
export const kubernetesDocumentationWeblinkId = "kubernetes-documentation-link";
|
||||||
|
|
||||||
export const docsUrl = "https://docs.k8slens.dev/main" as string;
|
export const docsUrl = "https://docs.k8slens.dev" as string;
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { getGlobalOverride } from "../test-utils/get-global-override";
|
|||||||
import applicationInformationInjectable from "./application-information.injectable";
|
import applicationInformationInjectable from "./application-information.injectable";
|
||||||
|
|
||||||
export default getGlobalOverride(applicationInformationInjectable, () => ({
|
export default getGlobalOverride(applicationInformationInjectable, () => ({
|
||||||
|
name: "some-product-name",
|
||||||
productName: "some-product-name",
|
productName: "some-product-name",
|
||||||
version: "6.0.0",
|
version: "6.0.0",
|
||||||
build: {},
|
build: {},
|
||||||
|
|||||||
@ -5,16 +5,16 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import packageJson from "../../../package.json";
|
import packageJson from "../../../package.json";
|
||||||
|
|
||||||
export type ApplicationInformation = Pick<typeof packageJson, "version" | "config" | "productName" | "copyright" | "description"> & {
|
export type ApplicationInformation = Pick<typeof packageJson, "version" | "config" | "productName" | "copyright" | "description" | "name"> & {
|
||||||
build: Partial<typeof packageJson["build"]> & { publish?: unknown[] };
|
build: Partial<typeof packageJson["build"]> & { publish?: unknown[] };
|
||||||
};
|
};
|
||||||
|
|
||||||
const applicationInformationInjectable = getInjectable({
|
const applicationInformationInjectable = getInjectable({
|
||||||
id: "application-information",
|
id: "application-information",
|
||||||
instantiate: (): ApplicationInformation => {
|
instantiate: (): ApplicationInformation => {
|
||||||
const { version, config, productName, build, copyright, description } = packageJson;
|
const { version, config, productName, build, copyright, description, name } = packageJson;
|
||||||
|
|
||||||
return { version, config, productName, build, copyright, description };
|
return { version, config, productName, build, copyright, description, name };
|
||||||
},
|
},
|
||||||
causesSideEffects: true,
|
causesSideEffects: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { getInjectionToken } from "@ogre-tools/injectable";
|
|||||||
import { SemVer } from "semver";
|
import { SemVer } from "semver";
|
||||||
import type { InitializableState } from "../initializable-state/create";
|
import type { InitializableState } from "../initializable-state/create";
|
||||||
import { createInitializableState } from "../initializable-state/create";
|
import { createInitializableState } from "../initializable-state/create";
|
||||||
import type { RequestChannel } from "../utils/channel/request-channel-injection-token";
|
import type { RequestChannel } from "../utils/channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
export const buildVersionInjectionToken = getInjectionToken<InitializableState<string>>({
|
export const buildVersionInjectionToken = getInjectionToken<InitializableState<string>>({
|
||||||
id: "build-version-token",
|
id: "build-version-token",
|
||||||
|
|||||||
@ -182,6 +182,7 @@ exports[`extension special characters in page registrations renders 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -302,6 +303,7 @@ exports[`extension special characters in page registrations when navigating to r
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -182,6 +182,7 @@ exports[`navigate to extension page renders 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -302,6 +303,7 @@ exports[`navigate to extension page when extension navigates to child route rend
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -438,6 +440,7 @@ exports[`navigate to extension page when extension navigates to route with param
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -574,6 +577,7 @@ exports[`navigate to extension page when extension navigates to route without pa
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -710,6 +714,7 @@ exports[`navigate to extension page when extension navigates to route without pa
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -106,6 +106,7 @@ exports[`navigating between routes given route with optional path parameters whe
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -226,6 +227,7 @@ exports[`navigating between routes given route without path parameters when navi
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -182,6 +182,7 @@ exports[`add-cluster - navigation using application menu renders 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -278,7 +279,7 @@ exports[`add-cluster - navigation using application menu when navigating to add
|
|||||||
</code>
|
</code>
|
||||||
file.
|
file.
|
||||||
<a
|
<a
|
||||||
href="https://docs.k8slens.dev/main/getting-started/add-cluster/"
|
href="https://docs.k8slens.dev/getting-started/add-cluster/"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
@ -386,6 +387,7 @@ exports[`add-cluster - navigation using application menu when navigating to add
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -201,6 +201,7 @@ exports[`force user to update when too long since update was downloaded when app
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -420,6 +421,7 @@ exports[`force user to update when too long since update was downloaded when app
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -686,6 +688,7 @@ exports[`force user to update when too long since update was downloaded when app
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -201,6 +201,7 @@ exports[`encourage user to update when sufficient time passed since update was d
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -402,6 +403,7 @@ exports[`encourage user to update when sufficient time passed since update was d
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -183,6 +183,7 @@ exports[`installing update using tray when started renders 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -384,6 +385,7 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -585,6 +587,7 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -804,6 +807,7 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1023,6 +1027,7 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1224,6 +1229,7 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -183,6 +183,7 @@ exports[`installing update when started renders 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -384,6 +385,7 @@ exports[`installing update when started when user checks for updates renders 1`]
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -585,6 +587,7 @@ exports[`installing update when started when user checks for updates when new up
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -804,6 +807,7 @@ exports[`installing update when started when user checks for updates when new up
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1023,6 +1027,7 @@ exports[`installing update when started when user checks for updates when new up
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1224,6 +1229,7 @@ exports[`installing update when started when user checks for updates when no new
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -183,6 +183,7 @@ exports[`periodical checking of updates given updater is enabled and configurati
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -183,6 +183,7 @@ exports[`selection of update stability when started renders 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -222,7 +222,7 @@ describe("selection of update stability", () => {
|
|||||||
it('given user changes update channel to "alpha", when user would close the application, installs the update for being stable enough', () => {
|
it('given user changes update channel to "alpha", when user would close the application, installs the update for being stable enough', () => {
|
||||||
selectedUpdateChannel.setValue(updateChannels.alpha.id);
|
selectedUpdateChannel.setValue(updateChannels.alpha.id);
|
||||||
|
|
||||||
expect(setUpdateOnQuitMock).toHaveBeenLastCalledWith(false);
|
expect(setUpdateOnQuitMock).toHaveBeenLastCalledWith(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -312,6 +312,7 @@ exports[`Deleting a cluster when an internal kubeconfig cluster is used when the
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -698,6 +699,7 @@ exports[`Deleting a cluster when the kubeconfig has multiple clusters when the d
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1117,6 +1119,7 @@ exports[`Deleting a cluster when the kubeconfig has multiple clusters when the d
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1615,6 +1618,7 @@ exports[`Deleting a cluster when the kubeconfig has multiple clusters when the d
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -2113,6 +2117,7 @@ exports[`Deleting a cluster when the kubeconfig has only one cluster when the di
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -1,20 +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 { ClusterId } from "../../../../common/cluster-types";
|
|
||||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-injection-token";
|
|
||||||
import { requestChannelInjectionToken } from "../../../../common/utils/channel/request-channel-injection-token";
|
|
||||||
|
|
||||||
export type ClearClusterAsDeletingChannel = RequestChannel<ClusterId, void>;
|
|
||||||
|
|
||||||
const clearClusterAsDeletingChannelInjectable = getInjectable({
|
|
||||||
id: "clear-cluster-as-deleting-channel",
|
|
||||||
instantiate: (): ClearClusterAsDeletingChannel => ({
|
|
||||||
id: "clear-cluster-as-deleting",
|
|
||||||
}),
|
|
||||||
injectionToken: requestChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default clearClusterAsDeletingChannelInjectable;
|
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
|
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type ClearClusterAsDeletingChannel = RequestChannel<ClusterId, void>;
|
||||||
|
|
||||||
|
export const clearClusterAsDeletingChannel: ClearClusterAsDeletingChannel = {
|
||||||
|
id: "clear-cluster-as-deleting",
|
||||||
|
};
|
||||||
@ -1,20 +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 { ClusterId } from "../../../../common/cluster-types";
|
|
||||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-injection-token";
|
|
||||||
import { requestChannelInjectionToken } from "../../../../common/utils/channel/request-channel-injection-token";
|
|
||||||
|
|
||||||
export type DeleteClusterChannel = RequestChannel<ClusterId, void>;
|
|
||||||
|
|
||||||
const deleteClusterChannelInjectable = getInjectable({
|
|
||||||
id: "delete-cluster-channel",
|
|
||||||
instantiate: (): DeleteClusterChannel => ({
|
|
||||||
id: "delete-cluster",
|
|
||||||
}),
|
|
||||||
injectionToken: requestChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default deleteClusterChannelInjectable;
|
|
||||||
12
src/features/cluster/delete-dialog/common/delete-channel.ts
Normal file
12
src/features/cluster/delete-dialog/common/delete-channel.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
|
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type DeleteClusterChannel = RequestChannel<ClusterId, void>;
|
||||||
|
|
||||||
|
export const deleteClusterChannel: DeleteClusterChannel = {
|
||||||
|
id: "delete-cluster",
|
||||||
|
};
|
||||||
@ -1,20 +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 { ClusterId } from "../../../../common/cluster-types";
|
|
||||||
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-injection-token";
|
|
||||||
import { requestChannelInjectionToken } from "../../../../common/utils/channel/request-channel-injection-token";
|
|
||||||
|
|
||||||
export type SetClusterAsDeletingChannel = RequestChannel<ClusterId, void>;
|
|
||||||
|
|
||||||
const setClusterAsDeletingChannelInjectable = getInjectable({
|
|
||||||
id: "set-cluster-as-deleting-channel",
|
|
||||||
instantiate: (): SetClusterAsDeletingChannel => ({
|
|
||||||
id: "set-cluster-as-deleting",
|
|
||||||
}),
|
|
||||||
injectionToken: requestChannelInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default setClusterAsDeletingChannelInjectable;
|
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
|
import type { RequestChannel } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
||||||
|
|
||||||
|
export type SetClusterAsDeletingChannel = RequestChannel<ClusterId, void>;
|
||||||
|
|
||||||
|
export const setClusterAsDeletingChannel: SetClusterAsDeletingChannel = {
|
||||||
|
id: "set-cluster-as-deleting",
|
||||||
|
};
|
||||||
@ -1,23 +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 { requestChannelListenerInjectionToken } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
|
||||||
import clustersThatAreBeingDeletedInjectable from "../../../../main/cluster/are-being-deleted.injectable";
|
|
||||||
import clearClusterAsDeletingChannelInjectable from "../common/clear-as-deleting-channel.injectable";
|
|
||||||
|
|
||||||
const clearClusterAsDeletingChannelHandlerInjectable = getInjectable({
|
|
||||||
id: "clear-cluster-as-deleting-channel-handler",
|
|
||||||
instantiate: (di) => {
|
|
||||||
const clustersThatAreBeingDeleted = di.inject(clustersThatAreBeingDeletedInjectable);
|
|
||||||
|
|
||||||
return {
|
|
||||||
channel: di.inject(clearClusterAsDeletingChannelInjectable),
|
|
||||||
handler: (clusterId) => clustersThatAreBeingDeleted.delete(clusterId),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
injectionToken: requestChannelListenerInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default clearClusterAsDeletingChannelHandlerInjectable;
|
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import clustersThatAreBeingDeletedInjectable from "../../../../main/cluster/are-being-deleted.injectable";
|
||||||
|
import { getRequestChannelListenerInjectable } from "../../../../main/utils/channel/channel-listeners/listener-tokens";
|
||||||
|
import { clearClusterAsDeletingChannel } from "../common/clear-as-deleting-channel";
|
||||||
|
|
||||||
|
const clearClusterAsDeletingChannelListenerInjectable = getRequestChannelListenerInjectable({
|
||||||
|
channel: clearClusterAsDeletingChannel,
|
||||||
|
handler: (di) => {
|
||||||
|
const clustersThatAreBeingDeleted = di.inject(clustersThatAreBeingDeletedInjectable);
|
||||||
|
|
||||||
|
return (clusterId) => {
|
||||||
|
clustersThatAreBeingDeleted.delete(clusterId);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default clearClusterAsDeletingChannelListenerInjectable;
|
||||||
@ -1,56 +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 appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
|
||||||
import clusterFramesInjectable from "../../../../common/cluster-frames.injectable";
|
|
||||||
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
|
|
||||||
import directoryForLensLocalStorageInjectable from "../../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable";
|
|
||||||
import deleteFileInjectable from "../../../../common/fs/delete-file.injectable";
|
|
||||||
import joinPathsInjectable from "../../../../common/path/join-paths.injectable";
|
|
||||||
import { requestChannelListenerInjectionToken } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
|
||||||
import deleteClusterChannelInjectable from "../common/delete-channel.injectable";
|
|
||||||
|
|
||||||
const deleteClusterChannelHandlerInjectable = getInjectable({
|
|
||||||
id: "delete-cluster-channel-handler",
|
|
||||||
instantiate: (di) => {
|
|
||||||
const appEventBus = di.inject(appEventBusInjectable);
|
|
||||||
const clusterStore = di.inject(clusterStoreInjectable);
|
|
||||||
const clusterFrames = di.inject(clusterFramesInjectable);
|
|
||||||
const joinPaths = di.inject(joinPathsInjectable);
|
|
||||||
const directoryForLensLocalStorage = di.inject(directoryForLensLocalStorageInjectable);
|
|
||||||
const deleteFile = di.inject(deleteFileInjectable);
|
|
||||||
|
|
||||||
return {
|
|
||||||
channel: di.inject(deleteClusterChannelInjectable),
|
|
||||||
handler: async (clusterId) =>{
|
|
||||||
appEventBus.emit({ name: "cluster", action: "remove" });
|
|
||||||
|
|
||||||
const cluster = clusterStore.getById(clusterId);
|
|
||||||
|
|
||||||
if (!cluster) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cluster.disconnect();
|
|
||||||
clusterFrames.delete(cluster.id);
|
|
||||||
|
|
||||||
// Remove from the cluster store as well, this should clear any old settings
|
|
||||||
clusterStore.clusters.delete(cluster.id);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// remove the local storage file
|
|
||||||
const localStorageFilePath = joinPaths(directoryForLensLocalStorage, `${cluster.id}.json`);
|
|
||||||
|
|
||||||
await deleteFile(localStorageFilePath);
|
|
||||||
} catch {
|
|
||||||
// ignore error
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
injectionToken: requestChannelListenerInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default deleteClusterChannelHandlerInjectable;
|
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import appEventBusInjectable from "../../../../common/app-event-bus/app-event-bus.injectable";
|
||||||
|
import clusterFramesInjectable from "../../../../common/cluster-frames.injectable";
|
||||||
|
import clusterStoreInjectable from "../../../../common/cluster-store/cluster-store.injectable";
|
||||||
|
import directoryForLensLocalStorageInjectable from "../../../../common/directory-for-lens-local-storage/directory-for-lens-local-storage.injectable";
|
||||||
|
import deleteFileInjectable from "../../../../common/fs/delete-file.injectable";
|
||||||
|
import joinPathsInjectable from "../../../../common/path/join-paths.injectable";
|
||||||
|
import { getRequestChannelListenerInjectable } from "../../../../main/utils/channel/channel-listeners/listener-tokens";
|
||||||
|
import { deleteClusterChannel } from "../common/delete-channel";
|
||||||
|
|
||||||
|
const deleteClusterChannelListenerInjectable = getRequestChannelListenerInjectable({
|
||||||
|
channel: deleteClusterChannel,
|
||||||
|
handler: (di) => {
|
||||||
|
const appEventBus = di.inject(appEventBusInjectable);
|
||||||
|
const clusterStore = di.inject(clusterStoreInjectable);
|
||||||
|
const clusterFrames = di.inject(clusterFramesInjectable);
|
||||||
|
const joinPaths = di.inject(joinPathsInjectable);
|
||||||
|
const directoryForLensLocalStorage = di.inject(directoryForLensLocalStorageInjectable);
|
||||||
|
const deleteFile = di.inject(deleteFileInjectable);
|
||||||
|
|
||||||
|
return async (clusterId) => {
|
||||||
|
appEventBus.emit({ name: "cluster", action: "remove" });
|
||||||
|
|
||||||
|
const cluster = clusterStore.getById(clusterId);
|
||||||
|
|
||||||
|
if (!cluster) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster.disconnect();
|
||||||
|
clusterFrames.delete(cluster.id);
|
||||||
|
|
||||||
|
// Remove from the cluster store as well, this should clear any old settings
|
||||||
|
clusterStore.clusters.delete(cluster.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// remove the local storage file
|
||||||
|
const localStorageFilePath = joinPaths(directoryForLensLocalStorage, `${cluster.id}.json`);
|
||||||
|
|
||||||
|
await deleteFile(localStorageFilePath);
|
||||||
|
} catch {
|
||||||
|
// ignore error
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default deleteClusterChannelListenerInjectable;
|
||||||
@ -1,23 +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 { requestChannelListenerInjectionToken } from "../../../../common/utils/channel/request-channel-listener-injection-token";
|
|
||||||
import clustersThatAreBeingDeletedInjectable from "../../../../main/cluster/are-being-deleted.injectable";
|
|
||||||
import setClusterAsDeletingChannelInjectable from "../common/set-as-deleting-channel.injectable";
|
|
||||||
|
|
||||||
const setClusterAsDeletingChannelHandlerInjectable = getInjectable({
|
|
||||||
id: "set-cluster-as-deleting-channel-handler",
|
|
||||||
instantiate: (di) => {
|
|
||||||
const clustersThatAreBeingDeleted = di.inject(clustersThatAreBeingDeletedInjectable);
|
|
||||||
|
|
||||||
return {
|
|
||||||
channel: di.inject(setClusterAsDeletingChannelInjectable),
|
|
||||||
handler: (clusterId) => clustersThatAreBeingDeleted.add(clusterId),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
injectionToken: requestChannelListenerInjectionToken,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default setClusterAsDeletingChannelHandlerInjectable;
|
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
|
*/
|
||||||
|
import clustersThatAreBeingDeletedInjectable from "../../../../main/cluster/are-being-deleted.injectable";
|
||||||
|
import { getRequestChannelListenerInjectable } from "../../../../main/utils/channel/channel-listeners/listener-tokens";
|
||||||
|
import { setClusterAsDeletingChannel } from "../common/set-as-deleting-channel";
|
||||||
|
|
||||||
|
const setClusterAsDeletingChannelHandlerInjectable = getRequestChannelListenerInjectable({
|
||||||
|
channel: setClusterAsDeletingChannel,
|
||||||
|
handler: (di) => {
|
||||||
|
const clustersThatAreBeingDeleted = di.inject(clustersThatAreBeingDeletedInjectable);
|
||||||
|
|
||||||
|
return (clusterId) => {
|
||||||
|
clustersThatAreBeingDeleted.add(clusterId);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default setClusterAsDeletingChannelHandlerInjectable;
|
||||||
@ -5,7 +5,7 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { ClusterId } from "../../../../common/cluster-types";
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
import requestFromChannelInjectable from "../../../../renderer/utils/channel/request-from-channel.injectable";
|
import requestFromChannelInjectable from "../../../../renderer/utils/channel/request-from-channel.injectable";
|
||||||
import clearClusterAsDeletingChannelInjectable from "../common/clear-as-deleting-channel.injectable";
|
import { clearClusterAsDeletingChannel } from "../common/clear-as-deleting-channel";
|
||||||
|
|
||||||
export type RequestClearClusterAsDeleting = (clusterId: ClusterId) => Promise<void>;
|
export type RequestClearClusterAsDeleting = (clusterId: ClusterId) => Promise<void>;
|
||||||
|
|
||||||
@ -13,7 +13,6 @@ const requestClearClusterAsDeletingInjectable = getInjectable({
|
|||||||
id: "request-clear-cluster-as-deleting",
|
id: "request-clear-cluster-as-deleting",
|
||||||
instantiate: (di): RequestClearClusterAsDeleting => {
|
instantiate: (di): RequestClearClusterAsDeleting => {
|
||||||
const requestChannel = di.inject(requestFromChannelInjectable);
|
const requestChannel = di.inject(requestFromChannelInjectable);
|
||||||
const clearClusterAsDeletingChannel = di.inject(clearClusterAsDeletingChannelInjectable);
|
|
||||||
|
|
||||||
return (clusterId) => requestChannel(clearClusterAsDeletingChannel, clusterId);
|
return (clusterId) => requestChannel(clearClusterAsDeletingChannel, clusterId);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { ClusterId } from "../../../../common/cluster-types";
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
import requestFromChannelInjectable from "../../../../renderer/utils/channel/request-from-channel.injectable";
|
import requestFromChannelInjectable from "../../../../renderer/utils/channel/request-from-channel.injectable";
|
||||||
import deleteClusterChannelInjectable from "../common/delete-channel.injectable";
|
import { deleteClusterChannel } from "../common/delete-channel";
|
||||||
|
|
||||||
export type RequestDeleteCluster = (clusterId: ClusterId) => Promise<void>;
|
export type RequestDeleteCluster = (clusterId: ClusterId) => Promise<void>;
|
||||||
|
|
||||||
@ -13,7 +13,6 @@ const requestDeleteClusterInjectable = getInjectable({
|
|||||||
id: "request-delete-cluster",
|
id: "request-delete-cluster",
|
||||||
instantiate: (di): RequestDeleteCluster => {
|
instantiate: (di): RequestDeleteCluster => {
|
||||||
const requestChannel = di.inject(requestFromChannelInjectable);
|
const requestChannel = di.inject(requestFromChannelInjectable);
|
||||||
const deleteClusterChannel = di.inject(deleteClusterChannelInjectable);
|
|
||||||
|
|
||||||
return (clusterId) => requestChannel(deleteClusterChannel, clusterId);
|
return (clusterId) => requestChannel(deleteClusterChannel, clusterId);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import type { ClusterId } from "../../../../common/cluster-types";
|
import type { ClusterId } from "../../../../common/cluster-types";
|
||||||
import requestFromChannelInjectable from "../../../../renderer/utils/channel/request-from-channel.injectable";
|
import requestFromChannelInjectable from "../../../../renderer/utils/channel/request-from-channel.injectable";
|
||||||
import setClusterAsDeletingChannelInjectable from "../common/set-as-deleting-channel.injectable";
|
import { setClusterAsDeletingChannel } from "../common/set-as-deleting-channel";
|
||||||
|
|
||||||
export type RequestSetClusterAsDeleting = (clusterId: ClusterId) => Promise<void>;
|
export type RequestSetClusterAsDeleting = (clusterId: ClusterId) => Promise<void>;
|
||||||
|
|
||||||
@ -13,7 +13,6 @@ const requestSetClusterAsDeletingInjectable = getInjectable({
|
|||||||
id: "request-set-cluster-as-deleting",
|
id: "request-set-cluster-as-deleting",
|
||||||
instantiate: (di): RequestSetClusterAsDeleting => {
|
instantiate: (di): RequestSetClusterAsDeleting => {
|
||||||
const requestChannel = di.inject(requestFromChannelInjectable);
|
const requestChannel = di.inject(requestFromChannelInjectable);
|
||||||
const setClusterAsDeletingChannel = di.inject(setClusterAsDeletingChannelInjectable);
|
|
||||||
|
|
||||||
return (clusterId) => requestChannel(setClusterAsDeletingChannel, clusterId);
|
return (clusterId) => requestChannel(setClusterAsDeletingChannel, clusterId);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -264,6 +264,7 @@ exports[`Command Pallet: keyboard shortcut tests when on linux renders 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -546,6 +547,7 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing ESC
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -828,6 +830,7 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing SHI
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1122,6 +1125,7 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing SHI
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1323,6 +1327,7 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS renders 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1524,6 +1529,7 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing ESC
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1725,6 +1731,7 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing SHI
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -1938,6 +1945,7 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing SHI
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -182,6 +182,7 @@ exports[`extensions - navigation using application menu renders 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
@ -274,7 +275,7 @@ exports[`extensions - navigation using application menu when navigating to exten
|
|||||||
<p>
|
<p>
|
||||||
Add new features via Lens Extensions. Check out the
|
Add new features via Lens Extensions. Check out the
|
||||||
<a
|
<a
|
||||||
href="https://docs.k8slens.dev/main/extensions/"
|
href="https://docs.k8slens.dev/extensions/"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
@ -408,6 +409,7 @@ exports[`extensions - navigation using application menu when navigating to exten
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="StatusBar"
|
class="StatusBar"
|
||||||
|
data-testid="status-bar"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="leftSide"
|
class="leftSide"
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
import type { RenderResult } from "@testing-library/react";
|
import type { RenderResult } from "@testing-library/react";
|
||||||
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
import type { ApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||||
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
import { getApplicationBuilder } from "../../renderer/components/test-utils/get-application-builder";
|
||||||
|
import downloadBinaryInjectable, { type DownloadBinary } from "../../common/fetch/download-binary.injectable";
|
||||||
|
import downloadJsonInjectable, { type DownloadJson } from "../../common/fetch/download-json.injectable";
|
||||||
import focusWindowInjectable from "../../renderer/navigation/focus-window.injectable";
|
import focusWindowInjectable from "../../renderer/navigation/focus-window.injectable";
|
||||||
|
|
||||||
// TODO: Make components free of side effects by making them deterministic
|
// TODO: Make components free of side effects by making them deterministic
|
||||||
@ -15,14 +17,20 @@ describe("extensions - navigation using application menu", () => {
|
|||||||
let builder: ApplicationBuilder;
|
let builder: ApplicationBuilder;
|
||||||
let rendered: RenderResult;
|
let rendered: RenderResult;
|
||||||
let focusWindowMock: jest.Mock;
|
let focusWindowMock: jest.Mock;
|
||||||
|
let downloadJson: jest.MockedFunction<DownloadJson>;
|
||||||
|
let downloadBinary: jest.MockedFunction<DownloadBinary>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
builder = getApplicationBuilder();
|
builder = getApplicationBuilder();
|
||||||
|
|
||||||
builder.beforeWindowStart((windowDi) => {
|
builder.beforeWindowStart((windowDi) => {
|
||||||
focusWindowMock = jest.fn();
|
focusWindowMock = jest.fn();
|
||||||
|
downloadJson = jest.fn().mockImplementation((url) => { throw new Error(`Unexpected call to downloadJson for url=${url}`); });
|
||||||
|
downloadBinary = jest.fn().mockImplementation((url) => { throw new Error(`Unexpected call to downloadJson for url=${url}`); });
|
||||||
|
|
||||||
windowDi.override(focusWindowInjectable, () => focusWindowMock);
|
windowDi.override(focusWindowInjectable, () => focusWindowMock);
|
||||||
|
windowDi.override(downloadJsonInjectable, () => downloadJson);
|
||||||
|
windowDi.override(downloadBinaryInjectable, () => downloadBinary);
|
||||||
});
|
});
|
||||||
|
|
||||||
rendered = await builder.render();
|
rendered = await builder.render();
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user