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

Merge branch 'master' into enhancement-ability-to-remove-subnamespaces

This commit is contained in:
Alex Andreev 2023-03-02 13:20:40 +03:00 committed by GitHub
commit 98dee49c3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
136 changed files with 2940 additions and 1256 deletions

54
.github/workflows/cron-test.yaml vendored Normal file
View File

@ -0,0 +1,54 @@
name: Cron Test
on:
schedule:
- cron: "0 0 * * 1" # Run on the first day over every week
jobs:
test:
name: cron unit tests on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, macos-11, windows-2019]
node-version: [16.x]
steps:
- name: Checkout Release from lens
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Add the current IP address, long hostname and short hostname record to /etc/hosts file
if: runner.os == 'Linux'
run: |
echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts
- name: Using Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Get npm cache directory path
if: ${{ runner.os != 'Windows' }}
id: npm-cache-dir-path
shell: bash
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
if: ${{ runner.os != 'Windows' }}
id: npm-cache # use this to check for `cache-hit` (`steps.npm-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.npm-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- uses: nick-fields/retry@v2
name: Install dependencies
with:
timeout_minutes: 20
max_attempts: 3
retry_on: error
command: npm ci
- run: npm run test:unit
name: Run tests

View File

@ -7,14 +7,80 @@ on:
branches:
- master
jobs:
test:
name: ${{ matrix.type }} tests on ${{ matrix.os }}
integration-test:
name: integration tests on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04, macos-11, windows-2019]
type: [unit, smoke]
node-version: [16.x]
steps:
- name: Checkout Release from lens
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Add the current IP address, long hostname and short hostname record to /etc/hosts file
if: runner.os == 'Linux'
run: |
echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts
- name: Using Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Get npm cache directory path
if: ${{ runner.os != 'Windows' }}
id: npm-cache-dir-path
shell: bash
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
- uses: actions/cache@v3
if: ${{ runner.os != 'Windows' }}
id: npm-cache # use this to check for `cache-hit` (`steps.npm-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.npm-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
- uses: nick-fields/retry@v2
name: Install dependencies
with:
timeout_minutes: 20
max_attempts: 3
retry_on: error
command: npm ci
- name: Install integration test dependencies
id: minikube
uses: medyagh/setup-minikube@master
with:
minikube-version: latest
if: ${{ runner.os == 'Linux' }}
- run: xvfb-run --auto-servernum --server-args='-screen 0, 1600x900x24' npm run test:integration
name: Run Linux integration tests
if: ${{ runner.os == 'Linux' }}
- run: npm run test:integration
name: Run macOS integration tests
shell: bash
if: ${{ runner.os == 'macOS' }}
- run: npm run test:integration
name: Run Windows integration tests
if: ${{ runner.os == 'Windows' }}
unit-test:
name: unit tests on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-20.04]
node-version: [16.x]
steps:
- name: Checkout Release from lens
@ -57,24 +123,3 @@ jobs:
- run: npm run test:unit
name: Run tests
if: ${{ matrix.type == 'unit' }}
- name: Install integration test dependencies
id: minikube
uses: medyagh/setup-minikube@master
with:
minikube-version: latest
if: ${{ runner.os == 'Linux' && matrix.type == 'smoke' }}
- run: xvfb-run --auto-servernum --server-args='-screen 0, 1600x900x24' npm run test:integration
name: Run Linux integration tests
if: ${{ runner.os == 'Linux' && matrix.type == 'smoke' }}
- run: npm run test:integration
name: Run macOS integration tests
shell: bash
if: ${{ runner.os == 'macOS' && matrix.type == 'smoke' }}
- run: npm run test:integration
name: Run Windows integration tests
if: ${{ runner.os == 'Windows' && matrix.type == 'smoke' }}

View File

@ -1,11 +1,11 @@
# Lens Desktop Core ("OpenLens")
[![Build Status](https://github.com/lensapp/lens/actions/workflows/test.yml/badge.svg)](https://github.com/lensapp/lens/actions/workflows/test.yml)
[![Chat on Slack](https://img.shields.io/badge/chat-on%20slack-blue.svg?logo=slack&longCache=true&style=flat)](https://k8slens.dev/slack.html)
<img src="https://upload.wikimedia.org/wikipedia/commons/1/17/Discourse_icon.svg" width=25>[Explore our Forums](https://forums.k8slens.dev)
## The Repository
This repository is where Team Lens develops the core of the [Lens Desktop](https://k8slens.dev) product together with the community.
This repository is where Team Lens develops the core of the [Lens Desktop](https://k8slens.dev) product together with the community.
The core is a library, powered by [Electron](https://www.electronjs.org/) and [React](https://reactjs.org/). Unlike generic Electron + React frameworks / boilerplates, it is very opinionated for creating Lens Desktop-like applications and has support for Lens Extensions.
@ -31,4 +31,4 @@ See [Contributing](https://docs.k8slens.dev/contributing/) page.
## License
See [License](LICENSE).
See [License](LICENSE).

View File

@ -7,15 +7,15 @@ To install your first extension you should goto the [extension page](lens://app/
This documentation describes:
* How to build, run, test, and publish an extension.
* How to take full advantage of the Lens Extension API.
* Where to find [guides](extensions/guides/README.md) and [code samples](https://github.com/lensapp/lens-extension-samples) to help get you started.
- How to build, run, test, and publish an extension.
- How to take full advantage of the Lens Extension API.
- Where to find [guides](extensions/guides/README.md) and [code samples](https://github.com/lensapp/lens-extension-samples) to help get you started.
## What Extensions Can Do
Here are some examples of what you can achieve with the Extension API:
* Add custom components & views in the UI - Extending the Lens Workbench
- Add custom components & views in the UI - Extending the Lens Workbench
For an overview of the Lens Extension API, refer to the [Common Capabilities](extensions/capabilities/common-capabilities.md) page. [Extension Guides Overview](extensions/guides/README.md) also includes a list of code samples and guides that illustrate various ways of using the Lens Extension API.
@ -23,11 +23,11 @@ For an overview of the Lens Extension API, refer to the [Common Capabilities](ex
Here is what each section of the Lens Extension API docs can help you with:
* **Getting Started** teaches fundamental concepts for building extensions with the Hello World sample.
* **Extension Capabilities** dissects Lens's Extension API into smaller categories and points you to more detailed topics.
* **Extension Guides** includes guides and code samples that explain specific usages of Lens Extension API.
* **Testing and Publishing** includes in-depth guides on various extension development topics, such as testing and publishing extensions.
* **API Reference** contains exhaustive references for the Lens Extension API, Contribution Points, and many other topics.
- **Getting Started** teaches fundamental concepts for building extensions with the Hello World sample.
- **Extension Capabilities** dissects Lens's Extension API into smaller categories and points you to more detailed topics.
- **Extension Guides** includes guides and code samples that explain specific usages of Lens Extension API.
- **Testing and Publishing** includes in-depth guides on various extension development topics, such as testing and publishing extensions.
- **API Reference** contains exhaustive references for the Lens Extension API, Contribution Points, and many other topics.
## What's New
@ -45,7 +45,7 @@ See the [Lens v4 to v5 extension migration notes](extensions/extension-migration
## Looking for Help
If you have questions for extension development, try asking on the [Lens Dev Slack](http://k8slens.slack.com/). It's a public chatroom for Lens developers, where Lens team members chime in from time to time.
If you have questions for extension development, try asking on the [Lens Forums](http://forums.k8slens.dev/). It's a public chatroom for Lens developers, where Lens team members chime in from time to time.
To provide feedback on the documentation or issues with the Lens Extension API, create new issues at [lensapp/lens](https://github.com/lensapp/lens/issues). Please use the labels `area/documentation` and/or `area/extension`.

View File

@ -10,33 +10,33 @@ edit_uri: ""
nav:
- Overview: README.md
- Getting Started:
- Overview: extensions/get-started/overview.md
- Your First Extension: extensions/get-started/your-first-extension.md
- Extension Anatomy: extensions/get-started/anatomy.md
- Wrapping Up: extensions/get-started/wrapping-up.md
- Overview: extensions/get-started/overview.md
- Your First Extension: extensions/get-started/your-first-extension.md
- Extension Anatomy: extensions/get-started/anatomy.md
- Wrapping Up: extensions/get-started/wrapping-up.md
- Extension Capabilities:
- Common Capabilities: extensions/capabilities/common-capabilities.md
- Styling: extensions/capabilities/styling.md
- Common Capabilities: extensions/capabilities/common-capabilities.md
- Styling: extensions/capabilities/styling.md
- Extension Guides:
- Overview: extensions/guides/README.md
- Generator: extensions/guides/generator.md
- Main Extension: extensions/guides/main-extension.md
- Renderer Extension: extensions/guides/renderer-extension.md
- Catalog: extensions/guides/catalog.md
- Resource Stack: extensions/guides/resource-stack.md
- Extending KubernetesCluster: extensions/guides/extending-kubernetes-cluster.md
- Stores: extensions/guides/stores.md
- Working with MobX: extensions/guides/working-with-mobx.md
- Protocol Handlers: extensions/guides/protocol-handlers.md
- IPC: extensions/guides/ipc.md
- Overview: extensions/guides/README.md
- Generator: extensions/guides/generator.md
- Main Extension: extensions/guides/main-extension.md
- Renderer Extension: extensions/guides/renderer-extension.md
- Catalog: extensions/guides/catalog.md
- Resource Stack: extensions/guides/resource-stack.md
- Extending KubernetesCluster: extensions/guides/extending-kubernetes-cluster.md
- Stores: extensions/guides/stores.md
- Working with MobX: extensions/guides/working-with-mobx.md
- Protocol Handlers: extensions/guides/protocol-handlers.md
- IPC: extensions/guides/ipc.md
- Testing and Publishing:
- Testing Extensions: extensions/testing-and-publishing/testing.md
- Publishing Extensions: extensions/testing-and-publishing/publishing.md
- Testing Extensions: extensions/testing-and-publishing/testing.md
- Publishing Extensions: extensions/testing-and-publishing/publishing.md
- API Reference: extensions/api/README.md
theme:
name: 'material'
name: "material"
highlightjs: true
language: 'en'
language: "en"
custom_dir: docs/custom_theme
favicon: img/favicon.ico
logo: img/lens-logo-icon.svg
@ -79,9 +79,9 @@ extra:
- icon: fontawesome/brands/twitter
link: https://twitter.com/k8slens
name: Lens on Twitter
- icon: fontawesome/brands/slack
link: http://k8slens.slack.com/
name: Lens on Slack
- icon: fontawesome/brands/discourse
link: https://forums.k8slens.dev/
name: Lens Forums
- icon: fontawesome/solid/link
link: https://k8slens.dev/
name: Lens Website

488
package-lock.json generated
View File

@ -3281,6 +3281,10 @@
"@jridgewell/sourcemap-codec": "1.4.14"
}
},
"node_modules/@k8slens/application": {
"resolved": "packages/technical-features/application",
"link": true
},
"node_modules/@k8slens/bump-version-for-cron": {
"resolved": "packages/bump-version-for-cron",
"link": true
@ -3297,6 +3301,10 @@
"resolved": "packages/extension-api",
"link": true
},
"node_modules/@k8slens/feature-core": {
"resolved": "packages/technical-features/feature-core",
"link": true
},
"node_modules/@k8slens/generate-tray-icons": {
"resolved": "packages/generate-tray-icons",
"link": true
@ -4647,55 +4655,55 @@
}
},
"node_modules/@ogre-tools/fp": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/fp/-/fp-12.0.1.tgz",
"integrity": "sha512-BzMhkI4wPnuI+hXJDbtHUXQn/uBjJLx3W0oDaIFV+lLpkneUU0oW9D5uZFHNOouzCgf67/tnmUC6Ohevbr7/VA==",
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/fp/-/fp-15.1.1.tgz",
"integrity": "sha512-WuLl0lBFjMHcy6o+HZLw2eN9zSUx6210DqLbhjo110PtpMvXqzQOIfmIiKv+awKxs7F2lIj1QUUJ6PpxCXVWSg==",
"peerDependencies": {
"lodash": "^4.17.21"
}
},
"node_modules/@ogre-tools/injectable": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable/-/injectable-12.0.1.tgz",
"integrity": "sha512-uOx8STN2wSc9hknDSTGqViyR89Vwg7rGacwrVNchgyo48/QJsmZZz6cd1Aw3nT4vr7ekjTc2lh0Rz6zGIv47hg==",
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable/-/injectable-15.1.1.tgz",
"integrity": "sha512-koB4z1FkaRbTEW77ULK1viVORlBCDnUtxAhxYiZrUzQcCvd7Fi4izs/YzDWLPc2HHay+EdJw11CuNC1JfzhaaA==",
"peerDependencies": {
"@ogre-tools/fp": "^12.0.0",
"@ogre-tools/fp": "*",
"lodash": "^4.17.21"
}
},
"node_modules/@ogre-tools/injectable-extension-for-auto-registration": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-extension-for-auto-registration/-/injectable-extension-for-auto-registration-12.0.1.tgz",
"integrity": "sha512-itKcxEJ/J8SKGD/Wwj0UYOA+/nqwnrwanhikY6qhlibj8guujX77Iip7vMBzJFc2nIrRaQRcpNV2eXe+tjQUdg==",
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-extension-for-auto-registration/-/injectable-extension-for-auto-registration-15.1.1.tgz",
"integrity": "sha512-kByRoG1FTWnB412nkF4GnKzim1ldLbSd9H2PUR6UF0EmjPg3QstyZXSE341bWlWZMAi/1HPiagfZ9E1wOP609w==",
"peerDependencies": {
"@ogre-tools/fp": "^12.0.0",
"@ogre-tools/injectable": "^12.0.0",
"@ogre-tools/fp": "*",
"@ogre-tools/injectable": "*",
"lodash": "^4.17.21"
}
},
"node_modules/@ogre-tools/injectable-extension-for-mobx": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-extension-for-mobx/-/injectable-extension-for-mobx-12.0.1.tgz",
"integrity": "sha512-M1penOpZfO3/rJMb6WN4IL86p9Lx9tOMCipiNkAyitNLGWfeDPG279JlCs9E3Uw8R9nkFPiw8Je2SLnwnM9o+A==",
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-extension-for-mobx/-/injectable-extension-for-mobx-15.1.1.tgz",
"integrity": "sha512-ZdIZGG9Zr/okGktICQFY5PzENerjdNAlwvuP1Na8bmIHJAs7yEwi6KlSuoOkZ1oNvQcHAsi9V2WVBh8jGyHN8g==",
"peerDependencies": {
"@ogre-tools/fp": "^12.0.0",
"@ogre-tools/injectable": "^12.0.0",
"@ogre-tools/fp": "*",
"@ogre-tools/injectable": "*",
"lodash": "^4.17.21",
"mobx": "^6.3.0"
}
},
"node_modules/@ogre-tools/injectable-react": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-react/-/injectable-react-12.0.1.tgz",
"integrity": "sha512-LAOh/EHKqk/pQcBRZUAz0VcJwgBeIPxHwlV/Apw0aEBBoMuYLsLZh47rES8sMYMV6N5x7oVfkjMscujY0DCgaQ==",
"version": "15.1.1",
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-react/-/injectable-react-15.1.1.tgz",
"integrity": "sha512-nJ1mH3FsL+9WbiWoIbs955rKONf/0jkw4UmEM2dBdi5dQ7G6MCZu/lh4sTcPm5u3g6ZoV7o6rUZjkwkM1qUcZw==",
"peerDependencies": {
"@ogre-tools/fp": "^12.0.0",
"@ogre-tools/injectable": "^12.0.0",
"@ogre-tools/fp": "*",
"@ogre-tools/injectable": "*",
"lodash": "^4.17.21",
"mobx": "^6.3.0",
"mobx-react": "^7.2.0",
"react": "^17.0.0",
"react-dom": "^17.0.0"
"react": "^17 || ^18",
"react-dom": "^17 || ^18"
}
},
"node_modules/@parcel/watcher": {
@ -5850,6 +5858,16 @@
"@types/node": "*"
}
},
"node_modules/@types/inquirer": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.3.tgz",
"integrity": "sha512-CzNkWqQftcmk2jaCWdBTf9Sm7xSw4rkI1zpU/Udw3HX5//adEZUIm9STtoRP1qgWj0CWQtJ9UTvqmO2NNjhMJw==",
"dev": true,
"dependencies": {
"@types/through": "*",
"rxjs": "^7.2.0"
}
},
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
@ -5951,15 +5969,6 @@
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
},
"node_modules/@types/jsonfile": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.1.tgz",
"integrity": "sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/keyv": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
@ -6061,8 +6070,7 @@
"node_modules/@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
},
"node_modules/@types/parse5": {
"version": "6.0.3",
@ -6376,6 +6384,15 @@
"@types/jest": "*"
}
},
"node_modules/@types/through": {
"version": "0.0.30",
"resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz",
"integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/tough-cookie": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz",
@ -8833,8 +8850,7 @@
"node_modules/chardet": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
"dev": true
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"node_modules/chart.js": {
"version": "2.9.4",
@ -9091,7 +9107,6 @@
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz",
"integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==",
"dev": true,
"engines": {
"node": ">=6"
},
@ -9140,7 +9155,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
"dev": true,
"engines": {
"node": ">=0.8"
}
@ -9975,7 +9989,6 @@
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
"integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
"dev": true,
"dependencies": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
@ -10514,7 +10527,6 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
"dev": true,
"dependencies": {
"clone": "^1.0.2"
},
@ -11073,6 +11085,11 @@
"safe-buffer": "~5.1.0"
}
},
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
},
"node_modules/ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@ -13145,7 +13162,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
"dev": true,
"dependencies": {
"chardet": "^0.7.0",
"iconv-lite": "^0.4.24",
@ -13159,7 +13175,6 @@
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
@ -13729,7 +13744,6 @@
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.3.0.tgz",
"integrity": "sha512-IN+XTzusCjR5VgntYFgxbxVx3WraPRnKehBFrf00cMSrtUuW9MsG9dhL6MWpY6MkjC3wVwoujfCDgZZCQwbswA==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.16.7",
"chalk": "^4.1.2",
@ -13763,7 +13777,6 @@
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@ -13877,8 +13890,7 @@
"node_modules/fs-monkey": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
"integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==",
"dev": true
"integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q=="
},
"node_modules/fs.realpath": {
"version": "1.0.0",
@ -15186,7 +15198,6 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
"dev": true,
"dependencies": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
@ -15202,7 +15213,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true,
"engines": {
"node": ">=4"
}
@ -20767,7 +20777,6 @@
"version": "3.4.13",
"resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.13.tgz",
"integrity": "sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg==",
"dev": true,
"dependencies": {
"fs-monkey": "^1.0.3"
},
@ -21647,8 +21656,7 @@
"node_modules/mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
"dev": true
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
},
"node_modules/nan": {
"version": "2.17.0",
@ -21746,8 +21754,7 @@
"node_modules/node-abort-controller": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz",
"integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==",
"dev": true
"integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ=="
},
"node_modules/node-addon-api": {
"version": "1.7.2",
@ -25391,7 +25398,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -25688,7 +25694,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"dependencies": {
"callsites": "^3.0.0"
},
@ -28089,6 +28094,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.2.tgz",
"integrity": "sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==",
"dev": true,
"bin": {
"rimraf": "dist/cjs/src/bin.js"
},
@ -28121,7 +28127,6 @@
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
"dev": true,
"engines": {
"node": ">=0.12.0"
}
@ -28162,7 +28167,6 @@
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
"integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
"dev": true,
"dependencies": {
"tslib": "^2.1.0"
}
@ -30262,7 +30266,6 @@
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"dependencies": {
"os-tmpdir": "~1.0.2"
},
@ -31300,7 +31303,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
"dev": true,
"dependencies": {
"defaults": "^1.0.3"
}
@ -32254,15 +32256,15 @@
"dependencies": {
"@astronautlabs/jsonpath": "^1.1.0",
"@hapi/call": "^9.0.1",
"@hapi/subtext": "^7.0.4",
"@hapi/subtext": "^7.1.0",
"@k8slens/node-fetch": "^6.4.0-beta.13",
"@kubernetes/client-node": "^0.18.1",
"@material-ui/styles": "^4.11.5",
"@ogre-tools/fp": "^12.0.1",
"@ogre-tools/injectable": "^12.0.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1",
"@ogre-tools/injectable-extension-for-mobx": "^12.0.1",
"@ogre-tools/injectable-react": "^12.0.1",
"@ogre-tools/fp": "^15.1.1",
"@ogre-tools/injectable": "^15.1.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
"@ogre-tools/injectable-extension-for-mobx": "^15.1.1",
"@ogre-tools/injectable-react": "^15.1.1",
"@sentry/electron": "^3.0.8",
"@sentry/integrations": "^6.19.3",
"@side/jest-runtime": "^1.1.0",
@ -32396,7 +32398,6 @@
"dompurify": "^2.4.4",
"electron": "^19.1.9",
"electron-builder": "^23.6.0",
"electron-notarize": "^0.3.0",
"esbuild": "^0.17.8",
"esbuild-loader": "^2.21.0",
"eslint": "^8.33.0",
@ -32461,6 +32462,7 @@
"node": ">=16 <17"
},
"peerDependencies": {
"@k8slens/application": "^6.4.0-beta.13",
"@types/byline": "^4.2.33",
"@types/chart.js": "^2.9.36",
"@types/color": "^3.0.3",
@ -32828,9 +32830,6 @@
"jest-watch-typeahead": "^2.2.1",
"lodash": "^4.17.21",
"ts-jest": "^29.0.3"
},
"bin": {
"lens-test": "bin/test.sh"
}
},
"packages/infrastructure/jest/node_modules/@jest/console": {
@ -34095,11 +34094,13 @@
}
},
"packages/infrastructure/webpack": {
"name": "@k8slens/webpack",
"version": "0.0.1",
"license": "MIT",
"dependencies": {
"@types/webpack-env": "^1.18.0",
"css-loader": "^6.7.2",
"fork-ts-checker-webpack-plugin": "^7.3.0",
"mini-css-extract-plugin": "^2.7.0",
"sass-loader": "^13.2.0",
"style-loader": "^3.3.1",
@ -34107,10 +34108,6 @@
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-node-externals": "^3.0.0"
},
"bin": {
"lens-build": "bin/build.sh",
"lens-remove-build": "bin/remove-build.sh"
}
},
"packages/infrastructure/webpack/node_modules/sass-loader": {
@ -34291,14 +34288,15 @@
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@k8slens/application": "^6.4.0-beta.13",
"@k8slens/core": "^6.4.0-beta.13",
"@k8slens/ensure-binaries": "^6.4.0-beta.13",
"@k8slens/generate-tray-icons": "^6.4.0-beta.13",
"@ogre-tools/fp": "^12.0.1",
"@ogre-tools/injectable": "^12.0.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1",
"@ogre-tools/injectable-extension-for-mobx": "^12.0.1",
"@ogre-tools/injectable-react": "^12.0.1",
"@ogre-tools/fp": "^15.1.1",
"@ogre-tools/injectable": "^15.1.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
"@ogre-tools/injectable-extension-for-mobx": "^15.1.1",
"@ogre-tools/injectable-react": "^15.1.1",
"mobx": "^6.8.0",
"rimraf": "^4.1.2"
},
@ -34465,7 +34463,9 @@
"version": "6.4.0-beta.13",
"license": "MIT",
"dependencies": {
"rimraf": "^4.1.2"
"chalk": "^5.2.0",
"inquirer": "^9.1.4",
"semver": "^7.3.8"
},
"bin": {
"create-release-pr": "dist/index.js"
@ -34473,23 +34473,10 @@
"devDependencies": {
"@swc/cli": "^0.1.61",
"@swc/core": "^1.3.35",
"@types/command-line-args": "^5.2.0",
"@types/fs-extra": "^11.0.1",
"@types/inquirer": "^9.0.3",
"@types/node": "^16.18.11",
"@types/semver": "^7.3.13",
"command-line-args": "^5.2.1",
"fs-extra": "^11.1.0",
"semver": "^7.3.8"
}
},
"packages/release-tool/node_modules/@types/fs-extra": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.1.tgz",
"integrity": "sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==",
"dev": true,
"dependencies": {
"@types/jsonfile": "*",
"@types/node": "*"
"rimraf": "^4.1.2"
}
},
"packages/release-tool/node_modules/@types/node": {
@ -34498,18 +34485,293 @@
"integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw==",
"dev": true
},
"packages/release-tool/node_modules/fs-extra": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz",
"integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==",
"dev": true,
"packages/release-tool/node_modules/ansi-escapes": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.0.0.tgz",
"integrity": "sha512-IG23inYII3dWlU2EyiAiGj6Bwal5GzsgPMwjYGvc1HPE2dgbj4ZB5ToWBKSquKw74nB3TIuOwaI6/jSULzfgrw==",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
"type-fest": "^3.0.0"
},
"engines": {
"node": ">=14.14"
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/ansi-regex": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
"integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
}
},
"packages/release-tool/node_modules/ansi-styles": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"packages/release-tool/node_modules/bl": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
"integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==",
"dependencies": {
"buffer": "^6.0.3",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"packages/release-tool/node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"packages/release-tool/node_modules/chalk": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz",
"integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"packages/release-tool/node_modules/cli-cursor": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
"integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
"dependencies": {
"restore-cursor": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/cli-width": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.0.0.tgz",
"integrity": "sha512-ZksGS2xpa/bYkNzN3BAw1wEjsLV/ZKOf/CCrJ/QOBsxx6fOARIkwTutxp1XIOIohi6HKmOFjMoK/XaqDVUpEEw==",
"engines": {
"node": ">= 12"
}
},
"packages/release-tool/node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
},
"packages/release-tool/node_modules/escape-string-regexp": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
"integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/figures": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz",
"integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==",
"dependencies": {
"escape-string-regexp": "^5.0.0",
"is-unicode-supported": "^1.2.0"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/inquirer": {
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.1.4.tgz",
"integrity": "sha512-9hiJxE5gkK/cM2d1mTEnuurGTAoHebbkX0BYl3h7iEg7FYfuNIom+nDfBCSWtvSnoSrWCeBxqqBZu26xdlJlXA==",
"dependencies": {
"ansi-escapes": "^6.0.0",
"chalk": "^5.1.2",
"cli-cursor": "^4.0.0",
"cli-width": "^4.0.0",
"external-editor": "^3.0.3",
"figures": "^5.0.0",
"lodash": "^4.17.21",
"mute-stream": "0.0.8",
"ora": "^6.1.2",
"run-async": "^2.4.0",
"rxjs": "^7.5.7",
"string-width": "^5.1.2",
"strip-ansi": "^7.0.1",
"through": "^2.3.6",
"wrap-ansi": "^8.0.1"
},
"engines": {
"node": ">=12.0.0"
}
},
"packages/release-tool/node_modules/is-interactive": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
"integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/is-unicode-supported": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
"integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/log-symbols": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz",
"integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==",
"dependencies": {
"chalk": "^5.0.0",
"is-unicode-supported": "^1.1.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/ora": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/ora/-/ora-6.1.2.tgz",
"integrity": "sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==",
"dependencies": {
"bl": "^5.0.0",
"chalk": "^5.0.0",
"cli-cursor": "^4.0.0",
"cli-spinners": "^2.6.1",
"is-interactive": "^2.0.0",
"is-unicode-supported": "^1.1.0",
"log-symbols": "^5.1.0",
"strip-ansi": "^7.0.1",
"wcwidth": "^1.0.1"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/restore-cursor": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
"integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
"dependencies": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dependencies": {
"eastasianwidth": "^0.2.0",
"emoji-regex": "^9.2.2",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/strip-ansi": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz",
"integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==",
"dependencies": {
"ansi-regex": "^6.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"packages/release-tool/node_modules/type-fest": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.6.0.tgz",
"integrity": "sha512-RqTRtKTzvPpNdDUp1dVkKQRunlPITk4mXeqFlAZoJsS+fLRn8AdPK0TcQDumGayhU7fjlBfiBjsq3pe3rIfXZQ==",
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"packages/release-tool/node_modules/wrap-ansi": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dependencies": {
"ansi-styles": "^6.1.0",
"string-width": "^5.0.1",
"strip-ansi": "^7.0.1"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"packages/semver": {
@ -34534,6 +34796,24 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.12.tgz",
"integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw==",
"dev": true
},
"packages/technical-features/application": {
"name": "@k8slens/application",
"version": "6.4.0-beta.13",
"license": "MIT",
"peerDependencies": {
"@ogre-tools/fp": "^15.1.1",
"@ogre-tools/injectable": "^15.1.1",
"lodash": "^4.17.15"
}
},
"packages/technical-features/feature-core": {
"name": "@k8slens/feature-core",
"version": "0.0.1",
"license": "MIT",
"peerDependencies": {
"@ogre-tools/injectable": "^15.1.1"
}
}
}
}

View File

@ -1,27 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
const { notarize } = require("electron-notarize");
exports.default = async function notarizing(context) {
const { electronPlatformName, appOutDir } = context;
if (electronPlatformName !== "darwin") {
return;
}
if (!process.env.APPLEID || !process.env.APPLEIDPASS) {
return;
}
const appName = context.packager.appInfo.productFilename;
return await notarize({
appBundleId: process.env.APPBUNDLEID || "io.kontena.lens-app",
appPath: `${appOutDir}/${appName}.app`,
appleId: process.env.APPLEID,
appleIdPassword: process.env.APPLEIDPASS,
ascProvider:process.env.ASCPROVIDER,
});
};

View File

@ -57,7 +57,7 @@
"test:unit": "jest --testPathIgnorePatterns integration",
"test:watch": "func() { jest ${1} --watch --testPathIgnorePatterns integration; }; func",
"lint": "PROD=true eslint --ext js,ts,tsx --max-warnings=0 .",
"lint:fix": "npm run lint --fix"
"lint:fix": "npm run lint -- --fix"
},
"config": {
"k8sProxyVersion": "0.3.0",
@ -130,11 +130,11 @@
"@k8slens/node-fetch": "^6.4.0-beta.13",
"@kubernetes/client-node": "^0.18.1",
"@material-ui/styles": "^4.11.5",
"@ogre-tools/fp": "^12.0.1",
"@ogre-tools/injectable": "^12.0.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1",
"@ogre-tools/injectable-extension-for-mobx": "^12.0.1",
"@ogre-tools/injectable-react": "^12.0.1",
"@ogre-tools/fp": "^15.1.1",
"@ogre-tools/injectable": "^15.1.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
"@ogre-tools/injectable-extension-for-mobx": "^15.1.1",
"@ogre-tools/injectable-react": "^15.1.1",
"@sentry/electron": "^3.0.8",
"@sentry/integrations": "^6.19.3",
"@side/jest-runtime": "^1.1.0",
@ -268,7 +268,6 @@
"dompurify": "^2.4.4",
"electron": "^19.1.9",
"electron-builder": "^23.6.0",
"electron-notarize": "^0.3.0",
"esbuild": "^0.17.8",
"esbuild-loader": "^2.21.0",
"eslint": "^8.33.0",
@ -330,6 +329,7 @@
"xterm-addon-fit": "^0.5.0"
},
"peerDependencies": {
"@k8slens/application": "^6.4.0-beta.13",
"@types/byline": "^4.2.33",
"@types/chart.js": "^2.9.36",
"@types/color": "^3.0.3",

View File

@ -74,8 +74,7 @@ describe("cluster-store", () => {
di.override(kubectlBinaryNameInjectable, () => "kubectl");
di.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
di.override(normalizedPlatformInjectable, () => "darwin");
createCluster = di.inject(createClusterInjectionToken);
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
writeJsonSync = di.inject(writeJsonSyncInjectable);
writeFileSync = di.inject(writeFileSyncInjectable);
writeBufferSync = di.inject(writeBufferSyncInjectable);
@ -85,6 +84,9 @@ describe("cluster-store", () => {
describe("empty config", () => {
beforeEach(async () => {
createCluster = di.inject(createClusterInjectionToken);
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
writeJsonSync("/some-directory-for-user-data/lens-cluster-store.json", {});
clusterStore = di.inject(clusterStoreInjectable);
clusterStore.load();
@ -198,6 +200,10 @@ describe("cluster-store", () => {
},
],
});
createCluster = di.inject(createClusterInjectionToken);
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
clusterStore = di.inject(clusterStoreInjectable);
clusterStore.load();
});
@ -249,6 +255,10 @@ describe("cluster-store", () => {
},
],
});
createCluster = di.inject(createClusterInjectionToken);
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
clusterStore = di.inject(clusterStoreInjectable);
clusterStore.load();
});
@ -262,6 +272,11 @@ describe("cluster-store", () => {
describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
beforeEach(() => {
di.override(storeMigrationVersionInjectable, () => "3.6.0");
createCluster = di.inject(createClusterInjectionToken);
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
writeJsonSync("/some-directory-for-user-data/lens-cluster-store.json", {
__internal__: {
migrations: {
@ -281,7 +296,6 @@ describe("cluster-store", () => {
});
writeBufferSync("/some-directory-for-user-data/icon_path", testDataIcon);
di.override(storeMigrationVersionInjectable, () => "3.6.0");
clusterStore = di.inject(clusterStoreInjectable);
clusterStore.load();

View File

@ -0,0 +1,61 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { DiContainer } from "@ogre-tools/injectable";
import kubectlApplyAllInjectable from "../../main/kubectl/kubectl-apply-all.injectable";
import { getDiForUnitTesting } from "../../main/getDiForUnitTesting";
import type { KubernetesCluster } from "../catalog-entities";
import readDirectoryInjectable from "../fs/read-directory.injectable";
import readFileInjectable from "../fs/read-file.injectable";
import createResourceStackInjectable from "../k8s/create-resource-stack.injectable";
import appPathsStateInjectable from "../app-paths/app-paths-state.injectable";
import directoryForUserDataInjectable from "../app-paths/directory-for-user-data/directory-for-user-data.injectable";
describe("create resource stack tests", () => {
let di: DiContainer;
let cluster: KubernetesCluster;
beforeEach(async () => {
di = getDiForUnitTesting({ doGeneralOverrides: true });
cluster = {
getId: () => "test-cluster",
} as any;
di.override(readDirectoryInjectable, () => () => Promise.resolve(["file1"]) as any);
di.override(readFileInjectable, () => () => Promise.resolve("filecontents"));
di.override(appPathsStateInjectable, () => ({
get: () => ({}),
}));
di.override(directoryForUserDataInjectable, () => "/some-directory-for-user-data");
});
describe("kubectlApplyFolder", () => {
it("returns response", async () => {
di.override(kubectlApplyAllInjectable, () => () => Promise.resolve({
callWasSuccessful: true as const,
response: "success",
}));
const createResourceStack = di.inject(createResourceStackInjectable);
const resourceStack = createResourceStack(cluster, "test");
const response = await resourceStack.kubectlApplyFolder("/foo/bar");
expect(response).toEqual("success");
});
it("throws on error", async () => {
di.override(kubectlApplyAllInjectable, () => () => Promise.resolve({
callWasSuccessful: false as const,
error: "No permissions",
}));
const createResourceStack = di.inject(createResourceStackInjectable);
const resourceStack = createResourceStack(cluster, "test");
await expect(() => resourceStack.kubectlApplyFolder("/foo/bar")).rejects.toThrow("No permissions");
});
});
});

View File

@ -30,9 +30,9 @@ describe("user store tests", () => {
get: () => "latest" as const,
init: async () => {},
}));
await di.inject(defaultUpdateChannelInjectable).init();
userStore = di.inject(userStoreInjectable);
});
describe("for an empty config", () => {
@ -42,6 +42,8 @@ describe("user store tests", () => {
writeJsonSync("/some-directory-for-user-data/lens-user-store.json", {});
writeJsonSync("/some-directory-for-user-data/kube_config", {});
userStore = di.inject(userStoreInjectable);
userStore.load();
});
@ -90,6 +92,8 @@ describe("user store tests", () => {
di.override(storeMigrationVersionInjectable, () => "10.0.0");
userStore = di.inject(userStoreInjectable);
userStore.load();
});

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { Environments, getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import { getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import type { CatalogEntityContextMenuContext, CatalogEntityMetadata, CatalogEntityStatus } from "../catalog";
import { CatalogCategory, CatalogEntity, categoryVersion } from "../catalog/catalog-entity";
import productNameInjectable from "../vars/product-name.injectable";
@ -32,7 +32,7 @@ export class WebLink extends CatalogEntity<CatalogEntityMetadata, WebLinkStatus,
onContextMenuOpen(context: CatalogEntityContextMenuContext) {
// NOTE: this is safe because `onContextMenuOpen` is only supposed to be called in the renderer
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.renderer);
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi("renderer");
const productName = di.inject(productNameInjectable);
const weblinkStore = di.inject(weblinkStoreInjectable);

View File

@ -0,0 +1,17 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { DiContainerForInjection } from "@ogre-tools/injectable";
export interface ApplicationConfig {
mode: string;
}
export interface Application {
start: () => Promise<void>;
readonly di: DiContainerForInjection;
}
export type CreateApplication = (config: ApplicationConfig) => Application;

View File

@ -2,13 +2,13 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "../../../vars/application-information-token";
const welcomeRouteConfigInjectable = getInjectable({
id: "welcome-route-config",
instantiate: (di) => di.inject(applicationInformationToken).config.welcomeRoute,
instantiate: (di) => di.inject(applicationInformationToken).welcomeRoute,
});
export default welcomeRouteConfigInjectable;

View File

@ -7,7 +7,7 @@ import type { ReadOptions } from "fs-extra";
import fse from "fs-extra";
/**
* NOTE: Add corrisponding a corrisponding override of this injecable in `src/test-utils/override-fs-with-fakes.ts`
* NOTE: Add corresponding override of this injectable in `src/test-utils/override-fs-with-fakes.ts`
*/
const fsInjectable = getInjectable({
id: "fs",

View File

@ -4,7 +4,6 @@
*/
import type { DiContainer } from "@ogre-tools/injectable";
import createClusterInjectable from "../../../main/create-cluster/create-cluster.injectable";
import clusterFrameContextForNamespacedResourcesInjectable from "../../../renderer/cluster-frame-context/for-namespaced-resources.injectable";
import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
@ -18,6 +17,10 @@ import { KubeApi } from "../kube-api";
import { KubeObject } from "../kube-object";
import { KubeObjectStore } from "../kube-object.store";
import maybeKubeApiInjectable from "../maybe-kube-api.injectable";
import { createClusterInjectionToken } from "../../cluster/create-cluster-injection-token";
// eslint-disable-next-line no-restricted-imports
import { KubeApi as ExternalKubeApi } from "../../../extensions/common-api/k8s-api";
class TestApi extends KubeApi<KubeObject> {
protected async checkPreferredVersion() {
@ -40,7 +43,7 @@ describe("ApiManager", () => {
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
di.override(storesAndApisCanBeCreatedInjectable, () => true);
const createCluster = di.inject(createClusterInjectable);
const createCluster = di.inject(createClusterInjectionToken);
di.override(hostedClusterInjectable, () => createCluster({
contextName: "some-context-name",
@ -54,7 +57,7 @@ describe("ApiManager", () => {
});
describe("registerApi", () => {
it("re-register store if apiBase changed", async () => {
it("re-register store if apiBase changed", () => {
const apiBase = "apis/v1/foo";
const fallbackApiBase = "/apis/extensions/v1beta1/foo";
const kubeApi = new TestApi({
@ -72,21 +75,48 @@ describe("ApiManager", () => {
logger: di.inject(loggerInjectable),
}, kubeApi);
apiManager.registerApi(apiBase, kubeApi);
apiManager.registerApi(kubeApi);
// Define to use test api for ingress store
Object.defineProperty(kubeStore, "api", { value: kubeApi });
apiManager.registerStore(kubeStore, [kubeApi]);
apiManager.registerStore(kubeStore);
// Test that store is returned with original apiBase
expect(apiManager.getStore(kubeApi)).toBe(kubeStore);
// Change apiBase similar as checkPreferredVersion does
Object.defineProperty(kubeApi, "apiBase", { value: fallbackApiBase });
apiManager.registerApi(fallbackApiBase, kubeApi);
apiManager.registerApi(kubeApi);
// Test that store is returned with new apiBase
expect(apiManager.getStore(kubeApi)).toBe(kubeStore);
});
});
describe("technical tests for autorun", () => {
it("given two extensions register apis with the same apibase, settle into using the second", () => {
const apiBase = "/apis/aquasecurity.github.io/v1alpha1/vulnerabilityreports";
const firstApi = Object.assign(new ExternalKubeApi({
objectConstructor: KubeObject,
apiBase,
kind: "VulnerabilityReport",
}), {
myField: 1,
});
const secondApi = Object.assign(new ExternalKubeApi({
objectConstructor: KubeObject,
apiBase,
kind: "VulnerabilityReport",
}), {
myField: 2,
});
void firstApi;
void secondApi;
expect(apiManager.getApi(apiBase)).toMatchObject({
myField: 2,
});
});
});
});

View File

@ -15,7 +15,6 @@ import setupAutoRegistrationInjectable from "../../../renderer/before-frame-star
import { createMockResponseFromString } from "../../../test-utils/mock-responses";
import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
import directoryForUserDataInjectable from "../../app-paths/directory-for-user-data/directory-for-user-data.injectable";
import createClusterInjectable from "../../../main/create-cluster/create-cluster.injectable";
import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
import apiManagerInjectable from "../api-manager/manager.injectable";
@ -23,6 +22,7 @@ import type { DiContainer } from "@ogre-tools/injectable";
import ingressApiInjectable from "../endpoints/ingress.api.injectable";
import loggerInjectable from "../../logger.injectable";
import maybeKubeApiInjectable from "../maybe-kube-api.injectable";
import { createClusterInjectionToken } from "../../cluster/create-cluster-injection-token";
describe("KubeApi", () => {
let fetchMock: AsyncFnMock<Fetch>;
@ -39,7 +39,7 @@ describe("KubeApi", () => {
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
di.override(storesAndApisCanBeCreatedInjectable, () => true);
const createCluster = di.inject(createClusterInjectable);
const createCluster = di.inject(createClusterInjectionToken);
di.override(hostedClusterInjectable, () => createCluster({
contextName: "some-context-name",

View File

@ -24,7 +24,6 @@ import setupAutoRegistrationInjectable from "../../../renderer/before-frame-star
import { createMockResponseFromStream, createMockResponseFromString } from "../../../test-utils/mock-responses";
import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
import directoryForUserDataInjectable from "../../app-paths/directory-for-user-data/directory-for-user-data.injectable";
import createClusterInjectable from "../../../main/create-cluster/create-cluster.injectable";
import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
import apiKubeInjectable from "../../../renderer/k8s/api-kube.injectable";
@ -36,6 +35,7 @@ import namespaceApiInjectable from "../endpoints/namespace.api.injectable";
// NOTE: this is fine because we are testing something that only exported
// eslint-disable-next-line no-restricted-imports
import { PodsApi } from "../../../extensions/common-api/k8s-api";
import { createClusterInjectionToken } from "../../cluster/create-cluster-injection-token";
describe("createKubeApiForRemoteCluster", () => {
let createKubeApiForRemoteCluster: CreateKubeApiForRemoteCluster;
@ -48,7 +48,7 @@ describe("createKubeApiForRemoteCluster", () => {
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
di.override(storesAndApisCanBeCreatedInjectable, () => true);
const createCluster = di.inject(createClusterInjectable);
const createCluster = di.inject(createClusterInjectionToken);
di.override(hostedClusterInjectable, () => createCluster({
contextName: "some-context-name",
@ -154,7 +154,7 @@ describe("KubeApi", () => {
fetchMock = asyncFn();
di.override(fetchInjectable, () => fetchMock);
const createCluster = di.inject(createClusterInjectable);
const createCluster = di.inject(createClusterInjectionToken);
const createKubeJsonApi = di.inject(createKubeJsonApiInjectable);
di.override(hostedClusterInjectable, () => createCluster({

View File

@ -41,19 +41,22 @@ export class ApiManager {
const apis = chain(this.dependencies.apis.get().values())
.concat(this.externalApis.values());
const removedApis = new Set(this.apis.values());
const newState = new Map(this.apis);
for (const api of apis) {
removedApis.delete(api);
this.apis.set(api.apiBase, api);
newState.set(api.apiBase, api);
}
for (const api of removedApis) {
for (const [apiBase, storedApi] of this.apis) {
for (const [apiBase, storedApi] of newState) {
if (storedApi === api) {
this.apis.delete(apiBase);
newState.delete(apiBase);
}
}
}
this.apis.replace(newState);
});
}

View File

@ -51,7 +51,7 @@ export class ResourceStack {
this.dependencies.logger.warn(`[RESOURCE-STACK]: failed to apply resources: ${result.error}`);
return "";
throw new Error(result.error);
}
/**

View File

@ -4,6 +4,4 @@
*/
// @experimental
export { applicationInformationToken } from "./vars/application-information-token";
export type { ApplicationInformation } from "./vars/application-information-token";
export { bundledExtensionInjectionToken } from "../extensions/extension-discovery/bundled-extension-token";

View File

@ -3,13 +3,20 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { createLogger, format } from "winston";
import type { Logger } from "./logger";
import winstonLoggerInjectable from "./winston-logger.injectable";
import { loggerTransportInjectionToken } from "./logger/transports";
const loggerInjectable = getInjectable({
id: "logger",
instantiate: (di): Logger => {
const baseLogger = di.inject(winstonLoggerInjectable);
const baseLogger = createLogger({
format: format.combine(
format.splat(),
format.simple(),
),
transports: di.injectMany(loggerTransportInjectionToken),
});
return {
debug: (message, ...data) => baseLogger.debug(message, ...data),

View File

@ -19,7 +19,10 @@ import asyncFn from "@async-fn/jest";
import { getPromiseStatus } from "../../test-utils/get-promise-status";
import { runInAction } from "mobx";
import type { RequestChannelHandler } from "../../../main/utils/channel/channel-listeners/listener-tokens";
import { getRequestChannelListenerInjectable } from "../../../main/utils/channel/channel-listeners/listener-tokens";
import {
getRequestChannelListenerInjectable,
requestChannelListenerInjectionToken,
} from "../../../main/utils/channel/channel-listeners/listener-tokens";
type TestMessageChannel = MessageChannel<string>;
type TestRequestChannel = RequestChannel<string, string>;
@ -199,21 +202,32 @@ 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",
const someChannelListenerInjectable = getInjectable({
id: "some-channel-listener",
instantiate: () => ({
channel: testRequestChannel,
handler: () => () => "irrelevant",
}),
injectionToken: requestChannelListenerInjectionToken,
});
testChannelListenerInMain2Injectable.id += "2";
const someOtherChannelListenerInjectable = getInjectable({
id: "some-other-channel-listener",
instantiate: () => ({
channel: testRequestChannel,
handler: () => () => "irrelevant",
}),
injectionToken: requestChannelListenerInjectionToken,
});
applicationBuilder.beforeApplicationStart((mainDi) => {
runInAction(() => {
mainDi.register(testChannelListenerInMainInjectable);
mainDi.register(testChannelListenerInMain2Injectable);
mainDi.register(someChannelListenerInjectable);
mainDi.register(someOtherChannelListenerInjectable);
});
});

View File

@ -19,7 +19,7 @@ const withOrphanPromiseInjectable = getInjectable({
toBeDecorated,
withErrorLoggingFor(() => "Orphan promise rejection encountered"),
withErrorSuppression,
);
) as ((...args: any[]) => any);
decorated(...args);
};

View File

@ -18,6 +18,6 @@ export const apiKubePrefix = "/api-kube"; // k8s cluster apis
// Links
export const issuesTrackerUrl = "https://github.com/lensapp/lens/issues" as string;
export const slackUrl = "https://k8slens.dev/slack.html" as string;
export const supportUrl = "https://docs.k8slens.dev/support/" as string;
export const docsUrl = "https://docs.k8slens.dev" as string;
export const forumsUrl = "https://forums.k8slens.dev" as string;

View File

@ -2,8 +2,8 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "./application-information-token";
const applicationCopyrightInjectable = getInjectable({
id: "application-copyright",

View File

@ -2,8 +2,8 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "./application-information-token";
const applicationDescriptionInjectable = getInjectable({
id: "application-description",

View File

@ -0,0 +1,30 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "@k8slens/application";
export const applicationInformationFakeInjectable = getInjectable({
id: "application-information-fake",
instantiate: () => ({
name: "some-product-name",
productName: "some-product-name",
version: "6.0.0",
updatingIsEnabled: false,
k8sProxyVersion: "0.2.1",
bundledKubectlVersion: "1.23.3",
bundledHelmVersion: "3.7.2",
sentryDsn: "",
contentSecurityPolicy:
"script-src 'unsafe-eval' 'self'; frame-src http://*.localhost:*/; img-src * data:",
welcomeRoute: "/welcome",
copyright: "some-copyright-information",
description: "some-descriptive-text",
}),
injectionToken: applicationInformationToken,
});

View File

@ -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 packageJson from "../../../package.json";
import { applicationInformationToken } from "../../common/vars/application-information-token";
const applicationInformationInjectable = getInjectable({
id: "application-information",
injectionToken: applicationInformationToken,
instantiate: () => {
const { version, config, productName, build, copyright, description, name } = packageJson;
return { version, config, productName, build, copyright, description, name };
},
causesSideEffects: true,
});
export default applicationInformationInjectable;

View File

@ -1,15 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectionToken } from "@ogre-tools/injectable";
import type packageJson from "../../../package.json";
export type ApplicationInformation = Pick<typeof packageJson, "version" | "config" | "productName" | "copyright" | "description" | "name"> & {
build: Partial<typeof packageJson["build"]> & { publish?: unknown[] };
};
export const applicationInformationToken = getInjectionToken<ApplicationInformation>({
id: "application-information-token",
});

View File

@ -1,24 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getGlobalOverride } from "../test-utils/get-global-override";
import applicationInformationInjectable from "./application-information-injectable";
export default getGlobalOverride(applicationInformationInjectable, () => ({
name: "some-product-name",
productName: "some-product-name",
version: "6.0.0",
build: {} as any,
config: {
k8sProxyVersion: "0.2.1",
bundledKubectlVersion: "1.23.3",
bundledHelmVersion: "3.7.2",
sentryDsn: "",
contentSecurityPolicy: "script-src 'unsafe-eval' 'self'; frame-src http://*.localhost:*/; img-src * data:",
welcomeRoute: "/welcome",
},
copyright: "some-copyright-information",
description: "some-descriptive-text",
}));

View File

@ -2,12 +2,12 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "./application-information-token";
const bundledKubectlVersionInjectable = getInjectable({
id: "bundled-kubectl-version",
instantiate: (di) => di.inject(applicationInformationToken).config.bundledKubectlVersion,
instantiate: (di) => di.inject(applicationInformationToken).bundledKubectlVersion,
});
export default bundledKubectlVersionInjectable;

View File

@ -2,12 +2,12 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "./application-information-token";
const contentSecurityPolicyInjectable = getInjectable({
id: "content-security-policy",
instantiate: (di) => di.inject(applicationInformationToken).config.contentSecurityPolicy,
instantiate: (di) => di.inject(applicationInformationToken).contentSecurityPolicy,
});
export default contentSecurityPolicyInjectable;

View File

@ -0,0 +1,14 @@
/**
* 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 nodeEnvInjectionToken from "./node-env-injection-token";
const nodeEnvFakeInjectable = getInjectable({
id: "node-env-fake",
instantiate: () => "production",
injectionToken: nodeEnvInjectionToken,
});
export default nodeEnvFakeInjectable;

View File

@ -2,8 +2,8 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "./application-information-token";
const productNameInjectable = getInjectable({
id: "product-name",

View File

@ -2,12 +2,12 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "./application-information-token";
const sentryDataSourceNameInjectable = getInjectable({
id: "sentry-data-source-name",
instantiate: (di) => di.inject(applicationInformationToken).config.sentryDsn,
instantiate: (di) => di.inject(applicationInformationToken).sentryDsn,
});
export default sentryDataSourceNameInjectable;

View File

@ -3,11 +3,10 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "./application-information-token";
const storeMigrationVersionInjectable = getInjectable({
id: "store-migration-version",
instantiate: (di) => di.inject(applicationInformationToken).version,
instantiate: () => "6.4.0",
});
export default storeMigrationVersionInjectable;

View File

@ -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 { createLogger, format } from "winston";
import { loggerTransportInjectionToken } from "./logger/transports";
const winstonLoggerInjectable = getInjectable({
id: "winston-logger",
instantiate: (di) => createLogger({
format: format.combine(
format.splat(),
format.simple(),
),
transports: di.injectMany(loggerTransportInjectionToken),
}),
});
export default winstonLoggerInjectable;

View File

@ -9,7 +9,7 @@ import {
createContainer,
getInjectable,
} from "@ogre-tools/injectable";
import { Environments, setLegacyGlobalDiForExtensionApi } from "./legacy-global-di-for-extension-api";
import { setLegacyGlobalDiForExtensionApi } from "./legacy-global-di-for-extension-api";
import { asLegacyGlobalObjectForExtensionApiWithModifications } from "./as-legacy-global-object-for-extension-api-with-modifications";
describe("asLegacyGlobalObjectForExtensionApiWithModifications", () => {
@ -25,7 +25,7 @@ describe("asLegacyGlobalObjectForExtensionApiWithModifications", () => {
jest.spyOn(di, "inject");
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
setLegacyGlobalDiForExtensionApi(di, "renderer");
someInjectable = getInjectable({
id: "some-injectable",

View File

@ -4,17 +4,11 @@
*/
import type { DiContainer } from "@ogre-tools/injectable";
export type Environments = "main" | "renderer";
const legacyGlobalDis = new Map<Environments, DiContainer>();
export enum Environments {
renderer,
main,
}
export const setLegacyGlobalDiForExtensionApi = (
di: DiContainer,
environment: Environments,
) => {
export const setLegacyGlobalDiForExtensionApi = (di: DiContainer, environment: Environments) => {
legacyGlobalDis.set(environment, di);
};

View File

@ -11,7 +11,7 @@ import isWindowsInjectable from "../../common/vars/is-windows.injectable";
import { asLegacyGlobalFunctionForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-function-for-extension-api";
import { getLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import getEnabledExtensionsInjectable from "./get-enabled-extensions/get-enabled-extensions.injectable";
import { slackUrl, issuesTrackerUrl } from "../../common/vars";
import { issuesTrackerUrl } from "../../common/vars";
import { buildVersionInjectionToken } from "../../common/vars/build-semantic-version.injectable";
import { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
import userStoreInjectable from "../../common/user-store/user-store.injectable";
@ -53,6 +53,9 @@ export const App = {
return di.inject(isLinuxInjectable);
},
slackUrl,
/**
* @deprecated This value is now `""` and is left here for backwards compatability.
*/
slackUrl: "",
issuesTrackerUrl,
} as const;

View File

@ -47,17 +47,29 @@ const getKubeApiDeps = (): KubeApiDependencies => {
};
};
export interface ExternalKubeApiOptions {
/**
* If `true` then on creation of the `KubeApi`instance a call to `apiManager.registerApi` will be
* made. This is `true` by default to maintain backwards compatability.
*
* Setting this to `false` might make `KubeObject`'s details drawer stop working.
*
* @default true
*/
autoRegister?: boolean;
}
// NOTE: this is done to preserve `instanceOf` behaviour
function KubeApiCstr<
Object extends KubeObject = KubeObject,
Data extends KubeJsonApiDataFor<Object> = KubeJsonApiDataFor<Object>,
>(opts: KubeApiOptions<Object, Data>) {
>({ autoRegister = true, ...opts }: KubeApiOptions<Object, Data> & ExternalKubeApiOptions) {
const api = new InternalKubeApi(getKubeApiDeps(), opts);
const di = getLegacyGlobalDiForExtensionApi();
const storesAndApisCanBeCreated = di.inject(storesAndApisCanBeCreatedInjectionToken);
if (storesAndApisCanBeCreated) {
if (storesAndApisCanBeCreated && autoRegister) {
apiManager.registerApi(api);
}
@ -72,7 +84,7 @@ export type KubeApi<
export const KubeApi = KubeApiCstr as unknown as new<
Object extends KubeObject = KubeObject,
Data extends KubeJsonApiDataFor<Object> = KubeJsonApiDataFor<Object>,
>(opts: KubeApiOptions<Object, Data>) => InternalKubeApi<Object, Data>;
>(opts: KubeApiOptions<Object, Data> & ExternalKubeApiOptions) => InternalKubeApi<Object, Data>;
/**
* @deprecated Switch to using `Common.createResourceStack` instead

View File

@ -8,8 +8,8 @@ import extensionLoaderInjectable from "../extension-loader/extension-loader.inje
import isCompatibleExtensionInjectable from "./is-compatible-extension/is-compatible-extension.injectable";
import extensionsStoreInjectable from "../extensions-store/extensions-store.injectable";
import extensionInstallationStateStoreInjectable from "../extension-installation-state-store/extension-installation-state-store.injectable";
import installExtensionInjectable from "../extension-installer/install-extension/install-extension.injectable";
import extensionPackageRootDirectoryInjectable from "../extension-installer/extension-package-root-directory/extension-package-root-directory.injectable";
import installExtensionInjectable from "../install-extension/install-extension.injectable";
import extensionPackageRootDirectoryInjectable from "../install-extension/extension-package-root-directory.injectable";
import readJsonFileInjectable from "../../common/fs/read-json-file.injectable";
import loggerInjectable from "../../common/logger.injectable";
import pathExistsInjectable from "../../common/fs/path-exists.injectable";

View File

@ -7,7 +7,7 @@ import type { FSWatcher } from "chokidar";
import { getDiForUnitTesting } from "../../main/getDiForUnitTesting";
import extensionDiscoveryInjectable from "../extension-discovery/extension-discovery.injectable";
import type { ExtensionDiscovery } from "../extension-discovery/extension-discovery";
import installExtensionInjectable from "../extension-installer/install-extension/install-extension.injectable";
import installExtensionInjectable from "../install-extension/install-extension.injectable";
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import { delay } from "../../renderer/utils";
import { observable, runInAction, when } from "mobx";

View File

@ -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 pathToNpmCliInjectable from "../../common/app-paths/path-to-npm-cli.injectable";
import loggerInjectable from "../../common/logger.injectable";
import { ExtensionInstaller } from "./extension-installer";
import extensionPackageRootDirectoryInjectable from "./extension-package-root-directory/extension-package-root-directory.injectable";
const extensionInstallerInjectable = getInjectable({
id: "extension-installer",
instantiate: (di) => new ExtensionInstaller({
extensionPackageRootDirectory: di.inject(extensionPackageRootDirectoryInjectable),
logger: di.inject(loggerInjectable),
pathToNpmCli: di.inject(pathToNpmCliInjectable),
}),
});
export default extensionInstallerInjectable;

View File

@ -1,78 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import AwaitLock from "await-lock";
import child_process from "child_process";
import type { Logger } from "../../common/logger";
const logModule = "[EXTENSION-INSTALLER]";
interface Dependencies {
readonly extensionPackageRootDirectory: string;
readonly logger: Logger;
readonly pathToNpmCli: string;
}
const baseNpmInstallArgs = [
"install",
"--audit=false",
"--fund=false",
// NOTE: we do not omit the `optional` dependencies because that is how we specify the non-bundled extensions
"--omit=dev",
"--omit=peer",
"--prefer-offline",
];
/**
* Installs dependencies for extensions
*/
export class ExtensionInstaller {
private readonly installLock = new AwaitLock();
constructor(private readonly dependencies: Dependencies) {}
/**
* Install single package using npm
*/
installPackage = async (name: string): Promise<void> => {
// Mutual exclusion to install packages in sequence
await this.installLock.acquireAsync();
try {
this.dependencies.logger.info(`${logModule} installing package from ${name} to ${this.dependencies.extensionPackageRootDirectory}`);
await this.npm(...baseNpmInstallArgs, name);
this.dependencies.logger.info(`${logModule} package ${name} installed to ${this.dependencies.extensionPackageRootDirectory}`);
} finally {
this.installLock.release();
}
};
private npm(...args: string[]): Promise<void> {
return new Promise((resolve, reject) => {
const child = child_process.fork(this.dependencies.pathToNpmCli, args, {
cwd: this.dependencies.extensionPackageRootDirectory,
silent: true,
env: {},
});
let stderr = "";
child.stderr?.on("data", data => {
stderr += String(data);
});
child.on("close", (code) => {
if (code !== 0) {
reject(new Error(stderr));
} else {
resolve();
}
});
child.on("error", error => {
reject(error);
});
});
}
}

View File

@ -1,13 +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 extensionInstallerInjectable from "../extension-installer.injectable";
const installExtensionInjectable = getInjectable({
id: "install-extension",
instantiate: (di) => di.inject(extensionInstallerInjectable).installPackage,
});
export default installExtensionInjectable;

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
const extensionPackageRootDirectoryInjectable = getInjectable({
id: "extension-package-root-directory",

View File

@ -0,0 +1,111 @@
/**
* 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 { fork } from "child_process";
import AwaitLock from "await-lock";
import pathToNpmCliInjectable from "../../common/app-paths/path-to-npm-cli.injectable";
import extensionPackageRootDirectoryInjectable from "./extension-package-root-directory.injectable";
import prefixedLoggerInjectable from "../../common/logger/prefixed-logger.injectable";
import readJsonFileInjectable from "../../common/fs/read-json-file.injectable";
import joinPathsInjectable from "../../common/path/join-paths.injectable";
import type { PackageJson } from "../common-api";
import writeJsonFileInjectable from "../../common/fs/write-json-file.injectable";
import { once } from "lodash";
import { isErrnoException } from "../../common/utils";
const baseNpmInstallArgs = [
"install",
"--save-optional",
"--audit=false",
"--fund=false",
// NOTE: we do not omit the `optional` dependencies because that is how we specify the non-bundled extensions
"--omit=dev",
"--omit=peer",
"--prefer-offline",
];
export type InstallExtension = (name: string) => Promise<void>;
const installExtensionInjectable = getInjectable({
id: "install-extension",
instantiate: (di): InstallExtension => {
const pathToNpmCli = di.inject(pathToNpmCliInjectable);
const extensionPackageRootDirectory = di.inject(extensionPackageRootDirectoryInjectable);
const readJsonFile = di.inject(readJsonFileInjectable);
const writeJsonFile = di.inject(writeJsonFileInjectable);
const joinPaths = di.inject(joinPathsInjectable);
const logger = di.inject(prefixedLoggerInjectable, "EXTENSION-INSTALLER");
const forkNpm = (...args: string[]) => new Promise<void>((resolve, reject) => {
const child = fork(pathToNpmCli, args, {
cwd: extensionPackageRootDirectory,
silent: true,
env: {},
});
let stderr = "";
child.stderr?.on("data", data => {
stderr += String(data);
});
child.on("close", (code) => {
if (code !== 0) {
reject(new Error(stderr));
} else {
resolve();
}
});
child.on("error", error => {
reject(error);
});
});
const packageJsonPath = joinPaths(extensionPackageRootDirectory, "package.json");
/**
* NOTES:
* - We have to keep the `package.json` because `npm install` removes files from `node_modules`
* if they are no longer in the `package.json`
* - In v6.2.X we saved bundled extensions as `"dependencies"` and external extensions as
* `"optionalDependencies"` at startup. This was done because `"optionalDependencies"` can
* fail to install and that is OK.
* - We continue to maintain this behavior here by only installing new dependencies as
* `"optionalDependencies"`
*/
const fixupPackageJson = once(async () => {
try {
const packageJson = await readJsonFile(packageJsonPath) as PackageJson;
delete packageJson.dependencies;
await writeJsonFile(packageJsonPath, packageJson);
} catch (error) {
if (isErrnoException(error) && error.code === "ENOENT") {
return;
}
throw error;
}
});
const installLock = new AwaitLock();
return async (name) => {
await installLock.acquireAsync();
await fixupPackageJson();
try {
logger.info(`installing package for extension "${name}"`);
await forkNpm(...baseNpmInstallArgs, name);
logger.info(`installed package for extension "${name}"`);
} finally {
installLock.release();
}
};
},
});
export default installExtensionInjectable;

View File

@ -3,16 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import {
Environments,
getEnvironmentSpecificLegacyGlobalDiForExtensionApi,
} from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import { getEnvironmentSpecificLegacyGlobalDiForExtensionApi } from "../as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import navigateInjectable from "../../main/start-main-application/lens-window/navigate.injectable";
export function navigate(url: string) {
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi(Environments.main);
const di = getEnvironmentSpecificLegacyGlobalDiForExtensionApi("main");
const navigate = di.inject(navigateInjectable);
return navigate(url);

View File

@ -107,11 +107,11 @@ exports[`extension special characters in page registrations renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -107,11 +107,11 @@ exports[`navigate to extension page renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -107,11 +107,11 @@ exports[`add-cluster - navigation using application menu renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -108,11 +108,11 @@ exports[`installing update when started renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -393,11 +393,11 @@ exports[`installing update when started when user checks for updates renders 1`]
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -678,11 +678,11 @@ exports[`installing update when started when user checks for updates when new up
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -988,11 +988,11 @@ exports[`installing update when started when user checks for updates when new up
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -1298,11 +1298,11 @@ exports[`installing update when started when user checks for updates when new up
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -1583,11 +1583,11 @@ exports[`installing update when started when user checks for updates when no new
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -133,11 +133,11 @@ exports[`encourage user to update when sufficient time passed since update was d
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -418,11 +418,11 @@ exports[`encourage user to update when sufficient time passed since update was d
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -108,11 +108,11 @@ exports[`installing update using tray when started renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -393,11 +393,11 @@ exports[`installing update using tray when started when user checks for updates
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -678,11 +678,11 @@ exports[`installing update using tray when started when user checks for updates
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -988,11 +988,11 @@ exports[`installing update using tray when started when user checks for updates
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -1298,11 +1298,11 @@ exports[`installing update using tray when started when user checks for updates
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -1583,11 +1583,11 @@ exports[`installing update using tray when started when user checks for updates
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -133,11 +133,11 @@ exports[`force user to update when too long since update was downloaded when app
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -443,11 +443,11 @@ exports[`force user to update when too long since update was downloaded when app
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -800,11 +800,11 @@ exports[`force user to update when too long since update was downloaded when app
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -108,11 +108,11 @@ exports[`periodical checking of updates given updater is enabled and configurati
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -108,11 +108,11 @@ exports[`selection of update stability when started renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -2,12 +2,12 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "../../../../../common/vars/application-information-token";
const publishIsConfiguredInjectable = getInjectable({
id: "publish-is-configured",
instantiate: (di) => Boolean(di.inject(applicationInformationToken).build.publish?.length),
instantiate: (di) => Boolean(di.inject(applicationInformationToken).updatingIsEnabled),
});
export default publishIsConfiguredInjectable;

View File

@ -108,11 +108,11 @@ exports[`opening catalog entity details panel renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -25,6 +25,17 @@ describe("opening catalog entity details panel", () => {
beforeEach(async () => {
builder = getApplicationBuilder();
builder.beforeWindowStart((windowDi) => {
// TODO: remove once ClusterStore can be used without overriding it
windowDi.override(getClusterByIdInjectable, () => (clusterId) => {
if (clusterId === cluster.id) {
return cluster;
}
return undefined;
});
});
builder.afterWindowStart((windowDi) => {
const createCluster = windowDi.inject(createClusterInjectable);
@ -78,15 +89,6 @@ describe("opening catalog entity details panel", () => {
clusterServerUrl: "https://localhost:9999",
});
// TODO: remove once ClusterStore can be used without overriding it
windowDi.override(getClusterByIdInjectable, () => (clusterId) => {
if (clusterId === cluster.id) {
return cluster;
}
return undefined;
});
// TODO: replace with proper entity source once syncing entities between main and windows is injectable
const catalogEntityRegistry = windowDi.inject(catalogEntityRegistryInjectable);

View File

@ -199,11 +199,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -575,11 +575,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing ESC
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -951,11 +951,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing SHI
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -1339,11 +1339,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing SHI
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -1624,11 +1624,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -1909,11 +1909,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing ESC
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -2194,11 +2194,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing SHI
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -2491,11 +2491,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing SHI
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -108,11 +108,11 @@ exports[`Showing correct entity settings renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -830,7 +830,40 @@ exports[`Showing correct entity settings when navigating to non-local cluster en
>
Proxy
</h2>
<section />
<section>
<section>
<div
class="SubTitle"
id="http-proxy"
>
HTTP Proxy
</div>
<div
class="Input theme round black"
>
<label
class="input-area flex gaps align-center"
id=""
>
<input
class="input box grow"
placeholder="http://<address>:<port>"
spellcheck="false"
value=""
/>
</label>
<div
class="input-info flex gaps"
/>
</div>
<small
class="hint"
>
HTTP Proxy server. Used for communicating with Kubernetes API.
</small>
</section>
</section>
</section>
</div>
<div

View File

@ -25,6 +25,17 @@ describe("Showing correct entity settings", () => {
beforeEach(async () => {
builder = getApplicationBuilder();
builder.beforeWindowStart((windowDi) => {
// TODO: remove once ClusterStore can be used without overriding it
windowDi.override(getClusterByIdInjectable, () => (clusterId) => {
if (clusterId === cluster.id) {
return cluster;
}
return undefined;
});
});
builder.afterWindowStart((windowDi) => {
const createCluster = windowDi.inject(createClusterInjectable);
@ -78,14 +89,6 @@ describe("Showing correct entity settings", () => {
clusterServerUrl: "https://localhost:9999",
});
// TODO: remove once ClusterStore can be used without overriding it
windowDi.override(getClusterByIdInjectable, () => (clusterId) => {
if (clusterId === cluster.id) {
return cluster;
}
return undefined;
});
// TODO: replace with proper entity source once syncing entities between main and windows is injectable
const catalogEntityRegistry = windowDi.inject(catalogEntityRegistryInjectable);

View File

@ -107,11 +107,11 @@ exports[`extensions - navigation using application menu renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -107,11 +107,11 @@ exports[`preferences - navigation using application menu renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -108,11 +108,11 @@ exports[`show-about-using-tray renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -108,11 +108,11 @@ exports[`status-bar-items-originating-from-extensions when application starts wh
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -108,11 +108,11 @@ exports[`extendability-using-extension-api given an extension with a weakly type
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -402,11 +402,11 @@ exports[`extendability-using-extension-api given an extension with top-bar items
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -687,11 +687,11 @@ exports[`extendability-using-extension-api given an extension with top-bar items
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -972,11 +972,11 @@ exports[`extendability-using-extension-api renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -107,11 +107,11 @@ exports[`welcome - navigation using application menu renders 1`] = `
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>
@ -1142,11 +1142,11 @@ exports[`welcome - navigation using application menu when navigated somewhere el
If you have any questions or feedback, please join our
<a
class="link"
href="https://k8slens.dev/slack.html"
href="https://forums.k8slens.dev"
rel="noreferrer"
target="_blank"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -22,7 +22,10 @@ const pickHighestAccuracy = (prev: ClusterDetectionResult, curr: ClusterDetectio
const detectMetadataWithFor = (cluster: Cluster) => async (clusterMetadataDetector: ClusterMetadataDetector) => {
try {
return await clusterMetadataDetector.detect(cluster);
return {
key: clusterMetadataDetector.key,
result: await clusterMetadataDetector.detect(cluster),
};
} catch {
return null;
}
@ -39,7 +42,12 @@ const detectClusterMetadataInjectable = getInjectable({
filter(isDefined),
(arg) => groupBy(arg, "key"),
(arg) => object.entries(arg),
map(([ key, results ]) => [key, reduce(results, pickHighestAccuracy)] as const),
map(([ key, detectionResults ]) => {
const results = detectionResults.map(({ result }) => result as ClusterDetectionResult);
const highestAccuracyResult = reduce(results, pickHighestAccuracy)?.value;
return [key, highestAccuracyResult] as const;
}),
filter(hasDefinedTupleValue),
);

View File

@ -0,0 +1,107 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { AppPaths } from "../../common/app-paths/app-path-injection-token";
import appPathsStateInjectable from "../../common/app-paths/app-paths-state.injectable";
import directoryForKubeConfigsInjectable from "../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
import directoryForUserDataInjectable from "../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import { ClusterMetadataKey } from "../../common/cluster-types";
import type { Cluster } from "../../common/cluster/cluster";
import { createClusterInjectionToken } from "../../common/cluster/create-cluster-injection-token";
import { getDiForUnitTesting } from "../getDiForUnitTesting";
import clusterDistributionDetectorInjectable from "./cluster-distribution-detector.injectable";
import clusterIdDetectorFactoryInjectable from "./cluster-id-detector.injectable";
import clusterLastSeenDetectorInjectable from "./cluster-last-seen-detector.injectable";
import clusterNodeCountDetectorInjectable from "./cluster-nodes-count-detector.injectable";
import type { DetectClusterMetadata } from "./detect-cluster-metadata.injectable";
import detectClusterMetadataInjectable from "./detect-cluster-metadata.injectable";
import requestClusterVersionInjectable from "./request-cluster-version.injectable";
describe("detect-cluster-metadata", () => {
let detectClusterMetadata: DetectClusterMetadata;
let cluster: Cluster;
beforeEach(async () => {
const di = getDiForUnitTesting({ doGeneralOverrides: true });
const lastSeenDetectMock = jest.fn().mockReturnValue(Promise.resolve({ value: "some-time-stamp", accuracy: 100 }));
const nodeCountDetectMock = jest.fn().mockReturnValue(Promise.resolve({ value: 42, accuracy: 100 }));
const clusterIdDetectMock = jest.fn().mockReturnValue(Promise.resolve({ value: "some-cluster-id", accuracy: 100 }));
const distributionDetectMock = jest.fn().mockReturnValue(Promise.resolve({ value: "some-distribution", accuracy: 100 }));
di.override(clusterLastSeenDetectorInjectable, () => {
return {
key: ClusterMetadataKey.LAST_SEEN,
detect: lastSeenDetectMock,
};
});
di.override(requestClusterVersionInjectable, () => () => Promise.resolve("some-cluster-version"));
di.override(clusterNodeCountDetectorInjectable, () => ({
key: ClusterMetadataKey.NODES_COUNT,
detect: nodeCountDetectMock,
}));
di.override(clusterIdDetectorFactoryInjectable, () => ({
key: ClusterMetadataKey.CLUSTER_ID,
detect: clusterIdDetectMock,
}));
di.override(clusterDistributionDetectorInjectable, () => ({
key: ClusterMetadataKey.DISTRIBUTION,
detect: distributionDetectMock,
}));
di.override(directoryForUserDataInjectable, () => "/some-user-store-path");
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
di.override(appPathsStateInjectable, () => ({
get: () => ({} as AppPaths),
set: () => {},
}));
detectClusterMetadata = di.inject(detectClusterMetadataInjectable);
const createCluster = di.inject(createClusterInjectionToken);
cluster = createCluster({
id: "some-id",
contextName: "some-context",
kubeConfigPath: "minikube-config.yml",
}, {
clusterServerUrl: "foo",
});
});
it("given some cluster, last seen time stamp is added to the metadata", async () => {
const metadata = await detectClusterMetadata(cluster);
expect(metadata.lastSeen).toEqual("some-time-stamp");
});
it("given some cluster, cluster version is added to the metadata", async () => {
const metadata = await detectClusterMetadata(cluster);
expect(metadata.version).toEqual("some-cluster-version");
});
it("given some cluster, id is added to the metadata", async () => {
const metadata = await detectClusterMetadata(cluster);
expect(metadata.id).toEqual("some-cluster-id");
});
it("given some cluster, node count is added to the metadata", async () => {
const metadata = await detectClusterMetadata(cluster);
expect(metadata.nodes).toEqual(42);
});
it("given some cluster, distribution is added to the metadata", async () => {
const metadata = await detectClusterMetadata(cluster);
expect(metadata.distribution).toEqual("some-distribution");
});
});

View File

@ -6,12 +6,12 @@
// Fix embedded kubeconfig paths under snap config
import { getInjectable } from "@ogre-tools/injectable";
import { applicationInformationToken } from "../../../common/vars/application-information-token";
import { clusterStoreMigrationInjectionToken } from "../../../common/cluster-store/migration-token";
import loggerInjectable from "../../../common/logger.injectable";
import isSnapPackageInjectable from "../../../common/vars/is-snap-package.injectable";
import type { ClusterModel } from "../../../common/cluster-types";
import pathExistsSyncInjectable from "../../../common/fs/path-exists-sync.injectable";
import { applicationInformationToken } from "@k8slens/application";
const clusterStoreSnapMigrationInjectable = getInjectable({
id: "cluster-store-snap-migration",

View File

@ -3,20 +3,17 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { DiContainer } from "@ogre-tools/injectable";
import { getInjectable } from "@ogre-tools/injectable";
import { runInAction } from "mobx";
import type { CreateApplication } from "../common/create-app";
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
import { getDi } from "./getDi";
import { registerInjectables } from "./register-injectables";
import startMainApplicationInjectable from "./start-main-application/start-main-application.injectable";
interface AppConfig {
di: DiContainer;
mode: string;
}
export function createApp(conf: AppConfig) {
const { di, mode } = conf;
export const createApplication: CreateApplication = (config) => {
const { mode } = config;
const di = getDi();
runInAction(() => {
di.register(getInjectable({
@ -28,9 +25,8 @@ export function createApp(conf: AppConfig) {
registerInjectables(di);
});
const startMainApplication = di.inject(startMainApplicationInjectable);
return {
start: () => startMainApplication(),
start: di.inject(startMainApplicationInjectable),
di,
};
}
};

View File

@ -3,15 +3,15 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { createContainer } from "@ogre-tools/injectable";
import { runInAction } from "mobx";
import applicationInformationInjectable from "../common/vars/application-information-injectable";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import { setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
export const getDi = () => {
const di = createContainer("main");
const environment = "main";
const di = createContainer(environment);
runInAction(() => {
di.register(applicationInformationInjectable);
});
registerMobX(di);
setLegacyGlobalDiForExtensionApi(di, environment);
return di;
};

View File

@ -4,9 +4,8 @@
*/
import { chunk } from "lodash/fp";
import type { DiContainer, Injectable } from "@ogre-tools/injectable";
import { createContainer, isInjectable, getInjectable } from "@ogre-tools/injectable";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import type { DiContainer } from "@ogre-tools/injectable";
import { isInjectable } from "@ogre-tools/injectable";
import spawnInjectable from "./child-process/spawn.injectable";
import initializeExtensionsInjectable from "./start-main-application/runnables/initialize-extensions.injectable";
import setupIpcMainHandlersInjectable from "./electron-app/runnables/setup-ipc-main-handlers/setup-ipc-main-handlers.injectable";
@ -25,45 +24,30 @@ import electronQuitAndInstallUpdateInjectable from "./electron-app/features/elec
import electronUpdaterIsActiveInjectable from "./electron-app/features/electron-updater-is-active.injectable";
import setUpdateOnQuitInjectable from "./electron-app/features/set-update-on-quit.injectable";
import waitUntilBundledExtensionsAreLoadedInjectable from "./start-main-application/lens-window/application-window/wait-until-bundled-extensions-are-loaded.injectable";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import electronInjectable from "./utils/resolve-system-proxy/electron.injectable";
import initializeClusterManagerInjectable from "./cluster/initialize-manager.injectable";
import type { GlobalOverride } from "../common/test-utils/get-global-override";
import applicationInformationInjectable from "../common/vars/application-information-injectable";
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
import { getOverrideFsWithFakes } from "../test-utils/override-fs-with-fakes";
import { getDi } from "./getDi";
export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) {
const {
doGeneralOverrides = false,
} = opts;
const di = createContainer("main");
di.register(getInjectable({
id: "node-env",
instantiate: () => "production",
injectionToken: nodeEnvInjectionToken,
}));
setLegacyGlobalDiForExtensionApi(di, Environments.main);
const di = getDi();
di.preventSideEffects();
const injectables = (
global.injectablePaths.main.paths
runInAction(() => {
const injectables = global.injectablePaths.main.paths
.map(path => require(path))
.flatMap(Object.values)
.filter(isInjectable)
) as Injectable<any, any, any>[];
.filter(isInjectable);
runInAction(() => {
registerMobX(di);
di.register(applicationInformationInjectable);
chunk(100)(injectables).forEach(chunkInjectables => {
di.register(...chunkInjectables);
});
for (const block of chunk(100)(injectables)) {
di.register(...block);
}
});
if (doGeneralOverrides) {

View File

@ -8,7 +8,8 @@ export { afterApplicationIsLoadedInjectionToken } from "./start-main-application
export { beforeApplicationIsLoadingInjectionToken } from "./start-main-application/runnable-tokens/before-application-is-loading-injection-token";
export { beforeElectronIsReadyInjectionToken } from "./start-main-application/runnable-tokens/before-electron-is-ready-injection-token";
export { onLoadOfApplicationInjectionToken } from "./start-main-application/runnable-tokens/on-load-of-application-injection-token";
export { createApp } from "./create-app";
export { createApplication } from "./create-app";
export type { CreateApplication, Application, ApplicationConfig } from "../common/create-app";
export * as Mobx from "mobx";
export * as mainExtensionApi from "../extensions/main-api";
export * as commonExtensionApi from "../extensions/common-api";

View File

@ -4,19 +4,14 @@
*/
import type { DiContainer } from "@ogre-tools/injectable";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import { runInAction } from "mobx";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
export function registerInjectables(di: DiContainer) {
setLegacyGlobalDiForExtensionApi(di, Environments.main);
runInAction(() => {
registerMobX(di);
autoRegister({
di,
requireContexts: [
targetModule: module,
getRequireContexts: () => [
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
@ -24,6 +19,4 @@ export function registerInjectables(di: DiContainer) {
],
});
});
return di;
}

View File

@ -13,9 +13,9 @@ import openLinkInBrowserInjectable from "../../../../common/utils/open-link-in-b
import getAbsolutePathInjectable from "../../../../common/path/get-absolute-path.injectable";
import lensResourcesDirInjectable from "../../../../common/vars/lens-resources-dir.injectable";
import isLinuxInjectable from "../../../../common/vars/is-linux.injectable";
import { applicationInformationToken } from "../../../../common/vars/application-information-token";
import pathExistsSyncInjectable from "../../../../common/fs/path-exists-sync.injectable";
import lensProxyCertificateInjectable from "../../../../common/certificate/lens-proxy-certificate.injectable";
import { applicationInformationToken } from "@k8slens/application";
export type ElectronWindowTitleBarStyle = "hiddenInset" | "hidden" | "default" | "customButtonsOnHover";

View File

@ -10,8 +10,8 @@ export const lensWebsiteLinkName = "Lens Website";
export const lensDocumentationWeblinkId = "lens-documentation-link";
export const lensDocumentationWeblinkName = "Lens Documentation";
export const lensSlackWeblinkId = "lens-slack-link";
export const lensSlackWeblinkName = "Lens Community Slack";
export const lensForumsWeblinkId = "lens-forums-link";
export const lensForumsWeblinkName = "Lens Forums";
export const lensTwitterWeblinkId = "lens-twitter-link";
export const lensTwitterWeblinkName = "Lens on Twitter";

View File

@ -3,7 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { docsUrl, slackUrl } from "../../../common/vars";
import { docsUrl, forumsUrl } from "../../../common/vars";
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
import { getInjectable } from "@ogre-tools/injectable";
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
@ -20,7 +20,7 @@ const v514WeblinkStoreMigrationInjectable = getInjectable({
weblinks.push(
{ id: "https://k8slens.dev", name: links.lensWebsiteLinkName, url: "https://k8slens.dev" },
{ id: docsUrl, name: links.lensDocumentationWeblinkName, url: docsUrl },
{ id: slackUrl, name: links.lensSlackWeblinkName, url: slackUrl },
{ id: forumsUrl, name: links.lensForumsWeblinkName, url: forumsUrl },
{ id: "https://twitter.com/k8slens", name: links.lensTwitterWeblinkName, url: "https://twitter.com/k8slens" },
{ id: "https://medium.com/k8slens", name: links.lensBlogWeblinkName, url: "https://medium.com/k8slens" },
{ id: "https://kubernetes.io/docs/home/", name: links.kubernetesDocumentationWeblinkName, url: "https://kubernetes.io/docs/home/" },

View File

@ -16,40 +16,40 @@ const v545Beta1WeblinkStoreMigrationInjectable = getInjectable({
const weblinksRaw = store.get("weblinks");
const weblinks = (Array.isArray(weblinksRaw) ? weblinksRaw : []) as WeblinkData[];
const lensWebsiteLink = weblinks.find(weblink => weblink.name === links.lensWebsiteLinkName);
const lensWebsite = weblinks.find(weblink => weblink.name === links.lensWebsiteLinkName);
if (lensWebsiteLink) {
lensWebsiteLink.id = links.lensWebsiteWeblinkId;
if (lensWebsite) {
lensWebsite.id = links.lensWebsiteWeblinkId;
}
const lensDocumentationWeblinkLink = weblinks.find(weblink => weblink.name === links.lensDocumentationWeblinkName);
const lensDocumentationWeblink = weblinks.find(weblink => weblink.name === links.lensDocumentationWeblinkName);
if (lensDocumentationWeblinkLink) {
lensDocumentationWeblinkLink.id = links.lensDocumentationWeblinkId;
if (lensDocumentationWeblink) {
lensDocumentationWeblink.id = links.lensDocumentationWeblinkId;
}
const lensSlackWeblinkLink = weblinks.find(weblink => weblink.name === links.lensSlackWeblinkName);
const lensForumsWeblink = weblinks.find(weblink => weblink.name === links.lensForumsWeblinkName);
if (lensSlackWeblinkLink) {
lensSlackWeblinkLink.id = links.lensSlackWeblinkId;
if (lensForumsWeblink) {
lensForumsWeblink.id = links.lensForumsWeblinkId;
}
const lensTwitterWeblinkLink = weblinks.find(weblink => weblink.name === links.lensTwitterWeblinkName);
const lensTwitterWeblink = weblinks.find(weblink => weblink.name === links.lensTwitterWeblinkName);
if (lensTwitterWeblinkLink) {
lensTwitterWeblinkLink.id = links.lensTwitterWeblinkId;
if (lensTwitterWeblink) {
lensTwitterWeblink.id = links.lensTwitterWeblinkId;
}
const lensBlogWeblinkLink = weblinks.find(weblink => weblink.name === links.lensBlogWeblinkName);
const lensBlogWeblink = weblinks.find(weblink => weblink.name === links.lensBlogWeblinkName);
if (lensBlogWeblinkLink) {
lensBlogWeblinkLink.id = links.lensBlogWeblinkId;
if (lensBlogWeblink) {
lensBlogWeblink.id = links.lensBlogWeblinkId;
}
const kubernetesDocumentationWeblinkLink = weblinks.find(weblink => weblink.name === links.kubernetesDocumentationWeblinkName);
const kubernetesDocumentationWeblink = weblinks.find(weblink => weblink.name === links.kubernetesDocumentationWeblinkName);
if (kubernetesDocumentationWeblinkLink) {
kubernetesDocumentationWeblinkLink.id = links.kubernetesDocumentationWeblinkId;
if (kubernetesDocumentationWeblink) {
kubernetesDocumentationWeblink.id = links.kubernetesDocumentationWeblinkId;
}
store.set("weblinks", weblinks);

View File

@ -3,12 +3,12 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { docsUrl, slackUrl } from "../../../common/vars";
import { docsUrl, forumsUrl } from "../../../common/vars";
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
import { getInjectable } from "@ogre-tools/injectable";
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
import { applicationInformationToken } from "../../../common/vars/application-information-token";
import { lensDocumentationWeblinkId, lensSlackWeblinkId } from "../links";
import { lensDocumentationWeblinkId, lensForumsWeblinkId } from "../links";
import { applicationInformationToken } from "@k8slens/application";
const currentVersionWeblinkStoreMigrationInjectable = getInjectable({
id: "current-version-weblink-store-migration",
@ -20,10 +20,10 @@ const currentVersionWeblinkStoreMigrationInjectable = getInjectable({
run(store) {
const weblinksRaw = store.get("weblinks");
const weblinks = (Array.isArray(weblinksRaw) ? weblinksRaw : []) as WeblinkData[];
const slackWeblink = weblinks.find(weblink => weblink.id === lensSlackWeblinkId);
const forumsWeblink = weblinks.find(weblink => weblink.id === lensForumsWeblinkId);
if (slackWeblink) {
slackWeblink.url = slackUrl;
if (forumsWeblink) {
forumsWeblink.url = forumsUrl;
}
const docsWeblink = weblinks.find(weblink => weblink.id === lensDocumentationWeblinkId);
@ -32,7 +32,9 @@ const currentVersionWeblinkStoreMigrationInjectable = getInjectable({
docsWeblink.url = docsUrl;
}
store.set("weblinks", weblinks);
const removedSlackLink = weblinks.filter(weblink => weblink.id !== "lens-slack-link");
store.set("weblinks", removedSlackLink);
},
};
},

View File

@ -46,9 +46,7 @@ export async function bootstrap(di: DiContainer) {
}
try {
await initializeApp(() => {
unmountComponentAtNode(rootElem);
});
await initializeApp(() => unmountComponentAtNode(rootElem));
} catch (error) {
console.error(`[BOOTSTRAP]: view initialization error: ${error}`, {
origin: location.href,

View File

@ -127,7 +127,7 @@
}
.catalogAvatar {
font-size: 1.2ch;
font-size: 1.2ch !important;
}
.views {

View File

@ -10,7 +10,7 @@ import type { IComputedValue } from "mobx";
import type { CarouselProps } from "react-material-ui-carousel";
import LegacyCarousel from "react-material-ui-carousel";
import { Icon } from "../icon";
import { slackUrl } from "../../../common/vars";
import { forumsUrl } from "../../../common/vars";
import { withInjectables } from "@ogre-tools/injectable-react";
import welcomeMenuItemsInjectable from "./welcome-menu-items/welcome-menu-items.injectable";
import type { WelcomeMenuRegistration } from "./welcome-menu-items/welcome-menu-registration";
@ -93,12 +93,12 @@ const NonInjectedWelcome = observer(({
<br />
{"If you have any questions or feedback, please join our "}
<a
href={slackUrl}
href={forumsUrl}
target="_blank"
rel="noreferrer"
className="link"
>
Lens Community slack channel
Lens Forums
</a>
.
</p>

View File

@ -9,7 +9,7 @@ import type { ErrorInfo } from "react";
import React from "react";
import { observer } from "mobx-react";
import { Button } from "../button";
import { issuesTrackerUrl, slackUrl } from "../../../common/vars";
import { issuesTrackerUrl, forumsUrl } from "../../../common/vars";
import type { SingleOrMany } from "../../utils";
import type { ObservableHistory } from "mobx-observable-history";
import { withInjectables } from "@ogre-tools/injectable-react";
@ -53,15 +53,15 @@ class NonInjectedErrorBoundary extends React.Component<ErrorBoundaryProps & Depe
</h5>
<p>
{"To help us improve the product please report bugs to "}
{"To help us improve the product please report bugs on"}
<a
href={slackUrl}
href={forumsUrl}
rel="noreferrer"
target="_blank"
>
Slack
Lens Forums
</a>
{" community or "}
{" or on our"}
<a
href={issuesTrackerUrl}
rel="noreferrer"

View File

@ -19,8 +19,8 @@ import storesAndApisCanBeCreatedInjectable from "../../stores-apis-can-be-create
import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable";
import directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.injectable";
import createClusterInjectable from "../../../main/create-cluster/create-cluster.injectable";
import type { PodStore } from "../+workloads-pods/store";
import { createClusterInjectionToken } from "../../../common/cluster/create-cluster-injection-token";
describe("kube-object-list-layout", () => {
let di: DiContainer;
@ -34,7 +34,7 @@ describe("kube-object-list-layout", () => {
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
di.override(storesAndApisCanBeCreatedInjectable, () => true);
const createCluster = di.inject(createClusterInjectable);
const createCluster = di.inject(createClusterInjectionToken);
di.override(hostedClusterInjectable, () => createCluster({
contextName: "some-context-name",

View File

@ -5,19 +5,16 @@
import "./components/app.scss";
import { bootstrap } from "./bootstrap";
import type { DiContainer } from "@ogre-tools/injectable";
import { getInjectable } from "@ogre-tools/injectable";
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
import { runInAction } from "mobx";
import { registerInjectables } from "./register-injectables";
import type { CreateApplication } from "../common/create-app";
import { getDi } from "./getDi";
interface AppConfig {
di: DiContainer;
mode: string;
}
export function createApp(conf: AppConfig) {
const { di, mode } = conf;
export const createApplication: CreateApplication = (config) => {
const { mode } = config;
const di = getDi();
runInAction(() => {
di.register(getInjectable({
@ -25,10 +22,12 @@ export function createApp(conf: AppConfig) {
instantiate: () => mode,
injectionToken: nodeEnvInjectionToken,
}));
registerInjectables(di);
});
return {
start: () => bootstrap(di),
di,
};
}
};

View File

@ -12,7 +12,6 @@ import emitAppEventInjectable from "../../../../common/app-event-bus/emit-event.
import loadExtensionsInjectable from "../../load-extensions.injectable";
import loggerInjectable from "../../../../common/logger.injectable";
import showErrorNotificationInjectable from "../../../components/notifications/show-error-notification.injectable";
import closeRendererLogFileInjectable from "../../../logger/close-renderer-log-file.injectable";
const initClusterFrameInjectable = getInjectable({
id: "init-cluster-frame",
@ -30,7 +29,6 @@ const initClusterFrameInjectable = getInjectable({
emitAppEvent: di.inject(emitAppEventInjectable),
logger: di.inject(loggerInjectable),
showErrorNotification: di.inject(showErrorNotificationInjectable),
closeFileLogging: di.inject(closeRendererLogFileInjectable),
});
},
});

View File

@ -2,7 +2,6 @@
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { once } from "lodash";
import type { Cluster } from "../../../../common/cluster/cluster";
import type { CatalogEntityRegistry } from "../../../api/catalog/entity/registry";
import type { ShowNotification } from "../../../components/notifications";
@ -19,7 +18,6 @@ interface Dependencies {
emitAppEvent: EmitAppEvent;
logger: Logger;
showErrorNotification: ShowNotification;
closeFileLogging: () => void;
}
const logPrefix = "[CLUSTER-FRAME]:";
@ -32,7 +30,6 @@ export const initClusterFrame = ({
emitAppEvent,
logger,
showErrorNotification,
closeFileLogging,
}: Dependencies) =>
async (unmountRoot: () => void) => {
// TODO: Make catalogEntityRegistry already initialized when passed as dependency
@ -76,14 +73,11 @@ export const initClusterFrame = ({
});
});
const onCloseFrame = once(() => {
window.onbeforeunload = () => {
logger.info(
`${logPrefix} Unload dashboard, clusterId=${(hostedCluster.id)}, frameId=${frameRoutingId}`,
);
closeFileLogging();
unmountRoot();
});
window.addEventListener("beforeunload", onCloseFrame);
window.addEventListener("pagehide", onCloseFrame);
unmountRoot();
};
};

View File

@ -13,7 +13,6 @@ import loggerInjectable from "../../../common/logger.injectable";
import { delay } from "../../../common/utils";
import { broadcastMessage } from "../../../common/ipc";
import { bundledExtensionsLoaded } from "../../../common/ipc/extension-handling";
import closeRendererLogFileInjectable from "../../logger/close-renderer-log-file.injectable";
const initRootFrameInjectable = getInjectable({
id: "init-root-frame",
@ -25,7 +24,6 @@ const initRootFrameInjectable = getInjectable({
const lensProtocolRouterRenderer = di.inject(lensProtocolRouterRendererInjectable);
const catalogEntityRegistry = di.inject(catalogEntityRegistryInjectable);
const logger = di.inject(loggerInjectable);
const closeRendererLogFile = di.inject(closeRendererLogFileInjectable);
return async (unmountRoot: () => void) => {
catalogEntityRegistry.init();
@ -61,7 +59,7 @@ const initRootFrameInjectable = getInjectable({
window.addEventListener("beforeunload", () => {
logger.info("[ROOT-FRAME]: Unload app");
closeRendererLogFile();
unmountRoot();
});
};

View File

@ -4,15 +4,17 @@
*/
import { createContainer } from "@ogre-tools/injectable";
import { runInAction } from "mobx";
import applicationInformationInjectable from "../common/vars/application-information-injectable";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import { registerInjectableReact } from "@ogre-tools/injectable-react";
import { setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
export const getDi = () => {
const di = createContainer("renderer");
const environment = "renderer";
const di = createContainer(environment);
runInAction(() => {
di.register(applicationInformationInjectable);
});
registerMobX(di);
registerInjectableReact(di);
setLegacyGlobalDiForExtensionApi(di, environment);
return di;
};

View File

@ -4,9 +4,7 @@
*/
import { noop, chunk } from "lodash/fp";
import type { Injectable } from "@ogre-tools/injectable";
import { createContainer, isInjectable, getInjectable } from "@ogre-tools/injectable";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import { isInjectable } from "@ogre-tools/injectable";
import requestFromChannelInjectable from "./utils/channel/request-from-channel.injectable";
import { getOverrideFsWithFakes } from "../test-utils/override-fs-with-fakes";
import terminalSpawningPoolInjectable from "./components/dock/terminal/terminal-spawning-pool.injectable";
@ -14,44 +12,29 @@ import hostedClusterIdInjectable from "./cluster-frame-context/hosted-cluster-id
import { runInAction } from "mobx";
import requestAnimationFrameInjectable from "./components/animate/request-animation-frame.injectable";
import startTopbarStateSyncInjectable from "./components/layout/top-bar/start-state-sync.injectable";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import watchHistoryStateInjectable from "./remote-helpers/watch-history-state.injectable";
import legacyOnChannelListenInjectable from "./ipc/legacy-channel-listen.injectable";
import type { GlobalOverride } from "../common/test-utils/get-global-override";
import applicationInformationInjectable from "../common/vars/application-information-injectable";
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
import { getDi } from "./getDi";
export const getDiForUnitTesting = (
opts: { doGeneralOverrides?: boolean } = {},
) => {
const { doGeneralOverrides = false } = opts;
const di = createContainer("renderer");
di.register(getInjectable({
id: "node-env",
instantiate: () => "production",
injectionToken: nodeEnvInjectionToken,
}));
const di = getDi();
di.preventSideEffects();
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
const injectables = (
global.injectablePaths.renderer.paths
runInAction(() => {
const injectables = global.injectablePaths.renderer.paths
.map(path => require(path))
.flatMap(Object.values)
.filter(isInjectable)
) as Injectable<any, any, any>[];
.filter(isInjectable);
runInAction(() => {
registerMobX(di);
di.register(applicationInformationInjectable);
chunk(100)(injectables).forEach((chunkInjectables) => {
di.register(...chunkInjectables);
});
for (const block of chunk(100)(injectables)) {
di.register(...block);
}
});
if (doGeneralOverrides) {

View File

@ -14,4 +14,5 @@ export * as ReactRouter from "react-router";
export * as ReactRouterDom from "react-router-dom";
export * as rendererExtensionApi from "../extensions/renderer-api";
export * as commonExtensionApi from "../extensions/common-api";
export { createApp } from "./create-app";
export { createApplication } from "./create-app";
export type { CreateApplication, Application, ApplicationConfig } from "../common/create-app";

View File

@ -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 winstonLoggerInjectable from "../../common/winston-logger.injectable";
import rendererFileLoggerTransportInjectable from "./file-transport.injectable";
const closeRendererLogFileInjectable = getInjectable({
id: "close-renderer-log-file",
instantiate: (di) => {
const winstonLogger = di.inject(winstonLoggerInjectable);
const fileLoggingTransport = di.inject(rendererFileLoggerTransportInjectable);
return () => {
fileLoggingTransport.close?.();
winstonLogger.remove(fileLoggingTransport);
};
},
});
export default closeRendererLogFileInjectable;

View File

@ -1,44 +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 { transports } from "winston";
import directoryForLogsInjectable from "../../common/app-paths/directory-for-logs.injectable";
import { loggerTransportInjectionToken } from "../../common/logger/transports";
import windowLocationInjectable from "../../common/k8s-api/window-location.injectable";
import currentlyInClusterFrameInjectable from "../routes/currently-in-cluster-frame.injectable";
import { getClusterIdFromHost } from "../utils";
const rendererFileLoggerTransportInjectable = getInjectable({
id: "renderer-file-logger-transport",
instantiate: (di) => {
let frameId: string;
const currentlyInClusterFrame = di.inject(
currentlyInClusterFrameInjectable,
);
if (currentlyInClusterFrame) {
const { host } = di.inject(windowLocationInjectable);
const clusterId = getClusterIdFromHost(host);
frameId = clusterId ? `cluster-${clusterId}` : "cluster";
} else {
frameId = "main";
}
return new transports.File({
handleExceptions: false,
level: "info",
filename: `lens-renderer-${frameId}.log`,
dirname: di.inject(directoryForLogsInjectable),
maxsize: 1024 * 1024,
maxFiles: 2,
tailable: true,
});
},
injectionToken: loggerTransportInjectionToken,
});
export default rendererFileLoggerTransportInjectable;

View File

@ -5,19 +5,14 @@
import type { DiContainer } from "@ogre-tools/injectable";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import { runInAction } from "mobx";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
export function registerInjectables(di: DiContainer) {
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
runInAction(() => {
registerMobX(di);
autoRegister({
di,
requireContexts: [
targetModule: module,
getRequireContexts: () => [
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
@ -25,6 +20,4 @@ export function registerInjectables(di: DiContainer) {
],
});
});
return di;
}

View File

@ -4,6 +4,10 @@
"version": "0.0.1",
"description": "Jest configuration and scripts for Lens packages.",
"type": "commonjs",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"repository": {
"type": "git",
"url": "git+https://github.com/lensapp/lens.git"
@ -15,9 +19,6 @@
},
"license": "MIT",
"homepage": "https://github.com/lensapp/lens",
"bin": {
"lens-test": "bin/test.sh"
},
"dependencies": {
"@swc/core": "^1.3.20",
"@swc/jest": "^0.2.23",

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