mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Merge remote-tracking branch 'origin/master' into issue-3498
Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
commit
9f4f4ec108
@ -1,11 +1,11 @@
|
|||||||
# Lens Desktop Core ("OpenLens")
|
# Lens Desktop Core ("OpenLens")
|
||||||
|
|
||||||
[](https://github.com/lensapp/lens/actions/workflows/test.yml)
|
[](https://github.com/lensapp/lens/actions/workflows/test.yml)
|
||||||
[](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
|
## 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.
|
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
|
## License
|
||||||
|
|
||||||
See [License](LICENSE).
|
See [License](LICENSE).
|
||||||
|
|||||||
@ -7,15 +7,15 @@ To install your first extension you should goto the [extension page](lens://app/
|
|||||||
|
|
||||||
This documentation describes:
|
This documentation describes:
|
||||||
|
|
||||||
* How to build, run, test, and publish an extension.
|
- How to build, run, test, and publish an extension.
|
||||||
* How to take full advantage of the Lens Extension API.
|
- 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.
|
- 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
|
## What Extensions Can Do
|
||||||
|
|
||||||
Here are some examples of what you can achieve with the Extension API:
|
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.
|
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:
|
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.
|
- **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 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.
|
- **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.
|
- **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.
|
- **API Reference** contains exhaustive references for the Lens Extension API, Contribution Points, and many other topics.
|
||||||
|
|
||||||
## What's New
|
## What's New
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ See the [Lens v4 to v5 extension migration notes](extensions/extension-migration
|
|||||||
|
|
||||||
## Looking for Help
|
## 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`.
|
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`.
|
||||||
|
|
||||||
|
|||||||
48
mkdocs.yml
48
mkdocs.yml
@ -10,33 +10,33 @@ edit_uri: ""
|
|||||||
nav:
|
nav:
|
||||||
- Overview: README.md
|
- Overview: README.md
|
||||||
- Getting Started:
|
- Getting Started:
|
||||||
- Overview: extensions/get-started/overview.md
|
- Overview: extensions/get-started/overview.md
|
||||||
- Your First Extension: extensions/get-started/your-first-extension.md
|
- Your First Extension: extensions/get-started/your-first-extension.md
|
||||||
- Extension Anatomy: extensions/get-started/anatomy.md
|
- Extension Anatomy: extensions/get-started/anatomy.md
|
||||||
- Wrapping Up: extensions/get-started/wrapping-up.md
|
- Wrapping Up: extensions/get-started/wrapping-up.md
|
||||||
- Extension Capabilities:
|
- Extension Capabilities:
|
||||||
- Common Capabilities: extensions/capabilities/common-capabilities.md
|
- Common Capabilities: extensions/capabilities/common-capabilities.md
|
||||||
- Styling: extensions/capabilities/styling.md
|
- Styling: extensions/capabilities/styling.md
|
||||||
- Extension Guides:
|
- Extension Guides:
|
||||||
- Overview: extensions/guides/README.md
|
- Overview: extensions/guides/README.md
|
||||||
- Generator: extensions/guides/generator.md
|
- Generator: extensions/guides/generator.md
|
||||||
- Main Extension: extensions/guides/main-extension.md
|
- Main Extension: extensions/guides/main-extension.md
|
||||||
- Renderer Extension: extensions/guides/renderer-extension.md
|
- Renderer Extension: extensions/guides/renderer-extension.md
|
||||||
- Catalog: extensions/guides/catalog.md
|
- Catalog: extensions/guides/catalog.md
|
||||||
- Resource Stack: extensions/guides/resource-stack.md
|
- Resource Stack: extensions/guides/resource-stack.md
|
||||||
- Extending KubernetesCluster: extensions/guides/extending-kubernetes-cluster.md
|
- Extending KubernetesCluster: extensions/guides/extending-kubernetes-cluster.md
|
||||||
- Stores: extensions/guides/stores.md
|
- Stores: extensions/guides/stores.md
|
||||||
- Working with MobX: extensions/guides/working-with-mobx.md
|
- Working with MobX: extensions/guides/working-with-mobx.md
|
||||||
- Protocol Handlers: extensions/guides/protocol-handlers.md
|
- Protocol Handlers: extensions/guides/protocol-handlers.md
|
||||||
- IPC: extensions/guides/ipc.md
|
- IPC: extensions/guides/ipc.md
|
||||||
- Testing and Publishing:
|
- Testing and Publishing:
|
||||||
- Testing Extensions: extensions/testing-and-publishing/testing.md
|
- Testing Extensions: extensions/testing-and-publishing/testing.md
|
||||||
- Publishing Extensions: extensions/testing-and-publishing/publishing.md
|
- Publishing Extensions: extensions/testing-and-publishing/publishing.md
|
||||||
- API Reference: extensions/api/README.md
|
- API Reference: extensions/api/README.md
|
||||||
theme:
|
theme:
|
||||||
name: 'material'
|
name: "material"
|
||||||
highlightjs: true
|
highlightjs: true
|
||||||
language: 'en'
|
language: "en"
|
||||||
custom_dir: docs/custom_theme
|
custom_dir: docs/custom_theme
|
||||||
favicon: img/favicon.ico
|
favicon: img/favicon.ico
|
||||||
logo: img/lens-logo-icon.svg
|
logo: img/lens-logo-icon.svg
|
||||||
@ -79,9 +79,9 @@ extra:
|
|||||||
- icon: fontawesome/brands/twitter
|
- icon: fontawesome/brands/twitter
|
||||||
link: https://twitter.com/k8slens
|
link: https://twitter.com/k8slens
|
||||||
name: Lens on Twitter
|
name: Lens on Twitter
|
||||||
- icon: fontawesome/brands/slack
|
- icon: fontawesome/brands/discourse
|
||||||
link: http://k8slens.slack.com/
|
link: https://forums.k8slens.dev/
|
||||||
name: Lens on Slack
|
name: Lens Forums
|
||||||
- icon: fontawesome/solid/link
|
- icon: fontawesome/solid/link
|
||||||
link: https://k8slens.dev/
|
link: https://k8slens.dev/
|
||||||
name: Lens Website
|
name: Lens Website
|
||||||
|
|||||||
447
package-lock.json
generated
447
package-lock.json
generated
@ -3301,6 +3301,10 @@
|
|||||||
"resolved": "packages/extension-api",
|
"resolved": "packages/extension-api",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@k8slens/feature-core": {
|
||||||
|
"resolved": "packages/technical-features/feature-core",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/@k8slens/generate-tray-icons": {
|
"node_modules/@k8slens/generate-tray-icons": {
|
||||||
"resolved": "packages/generate-tray-icons",
|
"resolved": "packages/generate-tray-icons",
|
||||||
"link": true
|
"link": true
|
||||||
@ -4651,55 +4655,55 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ogre-tools/fp": {
|
"node_modules/@ogre-tools/fp": {
|
||||||
"version": "12.0.1",
|
"version": "15.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ogre-tools/fp/-/fp-12.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ogre-tools/fp/-/fp-15.1.1.tgz",
|
||||||
"integrity": "sha512-BzMhkI4wPnuI+hXJDbtHUXQn/uBjJLx3W0oDaIFV+lLpkneUU0oW9D5uZFHNOouzCgf67/tnmUC6Ohevbr7/VA==",
|
"integrity": "sha512-WuLl0lBFjMHcy6o+HZLw2eN9zSUx6210DqLbhjo110PtpMvXqzQOIfmIiKv+awKxs7F2lIj1QUUJ6PpxCXVWSg==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"lodash": "^4.17.21"
|
"lodash": "^4.17.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ogre-tools/injectable": {
|
"node_modules/@ogre-tools/injectable": {
|
||||||
"version": "12.0.1",
|
"version": "15.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable/-/injectable-12.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable/-/injectable-15.1.1.tgz",
|
||||||
"integrity": "sha512-uOx8STN2wSc9hknDSTGqViyR89Vwg7rGacwrVNchgyo48/QJsmZZz6cd1Aw3nT4vr7ekjTc2lh0Rz6zGIv47hg==",
|
"integrity": "sha512-koB4z1FkaRbTEW77ULK1viVORlBCDnUtxAhxYiZrUzQcCvd7Fi4izs/YzDWLPc2HHay+EdJw11CuNC1JfzhaaA==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ogre-tools/fp": "^12.0.0",
|
"@ogre-tools/fp": "*",
|
||||||
"lodash": "^4.17.21"
|
"lodash": "^4.17.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ogre-tools/injectable-extension-for-auto-registration": {
|
"node_modules/@ogre-tools/injectable-extension-for-auto-registration": {
|
||||||
"version": "12.0.1",
|
"version": "15.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-extension-for-auto-registration/-/injectable-extension-for-auto-registration-12.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-extension-for-auto-registration/-/injectable-extension-for-auto-registration-15.1.1.tgz",
|
||||||
"integrity": "sha512-itKcxEJ/J8SKGD/Wwj0UYOA+/nqwnrwanhikY6qhlibj8guujX77Iip7vMBzJFc2nIrRaQRcpNV2eXe+tjQUdg==",
|
"integrity": "sha512-kByRoG1FTWnB412nkF4GnKzim1ldLbSd9H2PUR6UF0EmjPg3QstyZXSE341bWlWZMAi/1HPiagfZ9E1wOP609w==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ogre-tools/fp": "^12.0.0",
|
"@ogre-tools/fp": "*",
|
||||||
"@ogre-tools/injectable": "^12.0.0",
|
"@ogre-tools/injectable": "*",
|
||||||
"lodash": "^4.17.21"
|
"lodash": "^4.17.21"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ogre-tools/injectable-extension-for-mobx": {
|
"node_modules/@ogre-tools/injectable-extension-for-mobx": {
|
||||||
"version": "12.0.1",
|
"version": "15.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-extension-for-mobx/-/injectable-extension-for-mobx-12.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-extension-for-mobx/-/injectable-extension-for-mobx-15.1.1.tgz",
|
||||||
"integrity": "sha512-M1penOpZfO3/rJMb6WN4IL86p9Lx9tOMCipiNkAyitNLGWfeDPG279JlCs9E3Uw8R9nkFPiw8Je2SLnwnM9o+A==",
|
"integrity": "sha512-ZdIZGG9Zr/okGktICQFY5PzENerjdNAlwvuP1Na8bmIHJAs7yEwi6KlSuoOkZ1oNvQcHAsi9V2WVBh8jGyHN8g==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ogre-tools/fp": "^12.0.0",
|
"@ogre-tools/fp": "*",
|
||||||
"@ogre-tools/injectable": "^12.0.0",
|
"@ogre-tools/injectable": "*",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mobx": "^6.3.0"
|
"mobx": "^6.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ogre-tools/injectable-react": {
|
"node_modules/@ogre-tools/injectable-react": {
|
||||||
"version": "12.0.1",
|
"version": "15.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-react/-/injectable-react-12.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ogre-tools/injectable-react/-/injectable-react-15.1.1.tgz",
|
||||||
"integrity": "sha512-LAOh/EHKqk/pQcBRZUAz0VcJwgBeIPxHwlV/Apw0aEBBoMuYLsLZh47rES8sMYMV6N5x7oVfkjMscujY0DCgaQ==",
|
"integrity": "sha512-nJ1mH3FsL+9WbiWoIbs955rKONf/0jkw4UmEM2dBdi5dQ7G6MCZu/lh4sTcPm5u3g6ZoV7o6rUZjkwkM1qUcZw==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ogre-tools/fp": "^12.0.0",
|
"@ogre-tools/fp": "*",
|
||||||
"@ogre-tools/injectable": "^12.0.0",
|
"@ogre-tools/injectable": "*",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mobx": "^6.3.0",
|
"mobx": "^6.3.0",
|
||||||
"mobx-react": "^7.2.0",
|
"mobx-react": "^7.2.0",
|
||||||
"react": "^17.0.0",
|
"react": "^17 || ^18",
|
||||||
"react-dom": "^17.0.0"
|
"react-dom": "^17 || ^18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@parcel/watcher": {
|
"node_modules/@parcel/watcher": {
|
||||||
@ -5851,6 +5855,16 @@
|
|||||||
"@types/node": "*"
|
"@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": {
|
"node_modules/@types/istanbul-lib-coverage": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
|
||||||
@ -5952,15 +5966,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
|
||||||
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
|
"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": {
|
"node_modules/@types/keyv": {
|
||||||
"version": "3.1.4",
|
"version": "3.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
|
||||||
@ -6377,6 +6382,15 @@
|
|||||||
"@types/jest": "*"
|
"@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": {
|
"node_modules/@types/tough-cookie": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz",
|
||||||
@ -8834,8 +8848,7 @@
|
|||||||
"node_modules/chardet": {
|
"node_modules/chardet": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
|
||||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
|
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/chart.js": {
|
"node_modules/chart.js": {
|
||||||
"version": "2.9.4",
|
"version": "2.9.4",
|
||||||
@ -9092,7 +9105,6 @@
|
|||||||
"version": "2.6.1",
|
"version": "2.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz",
|
||||||
"integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==",
|
"integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
},
|
},
|
||||||
@ -9141,7 +9153,6 @@
|
|||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
|
||||||
"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
|
"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8"
|
"node": ">=0.8"
|
||||||
}
|
}
|
||||||
@ -10515,7 +10526,6 @@
|
|||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
|
||||||
"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
|
"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clone": "^1.0.2"
|
"clone": "^1.0.2"
|
||||||
},
|
},
|
||||||
@ -11074,6 +11084,11 @@
|
|||||||
"safe-buffer": "~5.1.0"
|
"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": {
|
"node_modules/ecc-jsbn": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||||
@ -13146,7 +13161,6 @@
|
|||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
||||||
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
|
"integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chardet": "^0.7.0",
|
"chardet": "^0.7.0",
|
||||||
"iconv-lite": "^0.4.24",
|
"iconv-lite": "^0.4.24",
|
||||||
@ -13160,7 +13174,6 @@
|
|||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3"
|
"safer-buffer": ">= 2.1.2 < 3"
|
||||||
},
|
},
|
||||||
@ -21648,8 +21661,7 @@
|
|||||||
"node_modules/mute-stream": {
|
"node_modules/mute-stream": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
|
||||||
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
|
"integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/nan": {
|
"node_modules/nan": {
|
||||||
"version": "2.17.0",
|
"version": "2.17.0",
|
||||||
@ -25392,7 +25404,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||||
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
|
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -28090,6 +28101,7 @@
|
|||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.1.2.tgz",
|
||||||
"integrity": "sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==",
|
"integrity": "sha512-BlIbgFryTbw3Dz6hyoWFhKk+unCcHMSkZGrTFVAx2WmttdBSonsdtRlwiuTbDqTKr+UlXIUqJVS4QT5tUzGENQ==",
|
||||||
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"rimraf": "dist/cjs/src/bin.js"
|
"rimraf": "dist/cjs/src/bin.js"
|
||||||
},
|
},
|
||||||
@ -28122,7 +28134,6 @@
|
|||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
||||||
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
|
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.12.0"
|
"node": ">=0.12.0"
|
||||||
}
|
}
|
||||||
@ -28163,7 +28174,6 @@
|
|||||||
"version": "7.8.0",
|
"version": "7.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
|
||||||
"integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
|
"integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.1.0"
|
"tslib": "^2.1.0"
|
||||||
}
|
}
|
||||||
@ -30263,7 +30273,6 @@
|
|||||||
"version": "0.0.33",
|
"version": "0.0.33",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||||
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
|
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"os-tmpdir": "~1.0.2"
|
"os-tmpdir": "~1.0.2"
|
||||||
},
|
},
|
||||||
@ -31301,7 +31310,6 @@
|
|||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
|
||||||
"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
|
"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"defaults": "^1.0.3"
|
"defaults": "^1.0.3"
|
||||||
}
|
}
|
||||||
@ -32259,11 +32267,11 @@
|
|||||||
"@k8slens/node-fetch": "^6.4.0-beta.13",
|
"@k8slens/node-fetch": "^6.4.0-beta.13",
|
||||||
"@kubernetes/client-node": "^0.18.1",
|
"@kubernetes/client-node": "^0.18.1",
|
||||||
"@material-ui/styles": "^4.11.5",
|
"@material-ui/styles": "^4.11.5",
|
||||||
"@ogre-tools/fp": "^12.0.1",
|
"@ogre-tools/fp": "^15.1.1",
|
||||||
"@ogre-tools/injectable": "^12.0.1",
|
"@ogre-tools/injectable": "^15.1.1",
|
||||||
"@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1",
|
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
|
||||||
"@ogre-tools/injectable-extension-for-mobx": "^12.0.1",
|
"@ogre-tools/injectable-extension-for-mobx": "^15.1.1",
|
||||||
"@ogre-tools/injectable-react": "^12.0.1",
|
"@ogre-tools/injectable-react": "^15.1.1",
|
||||||
"@sentry/electron": "^3.0.8",
|
"@sentry/electron": "^3.0.8",
|
||||||
"@sentry/integrations": "^6.19.3",
|
"@sentry/integrations": "^6.19.3",
|
||||||
"@side/jest-runtime": "^1.1.0",
|
"@side/jest-runtime": "^1.1.0",
|
||||||
@ -34290,11 +34298,11 @@
|
|||||||
"@k8slens/core": "^6.4.0-beta.13",
|
"@k8slens/core": "^6.4.0-beta.13",
|
||||||
"@k8slens/ensure-binaries": "^6.4.0-beta.13",
|
"@k8slens/ensure-binaries": "^6.4.0-beta.13",
|
||||||
"@k8slens/generate-tray-icons": "^6.4.0-beta.13",
|
"@k8slens/generate-tray-icons": "^6.4.0-beta.13",
|
||||||
"@ogre-tools/fp": "^12.0.1",
|
"@ogre-tools/fp": "^15.1.1",
|
||||||
"@ogre-tools/injectable": "^12.0.1",
|
"@ogre-tools/injectable": "^15.1.1",
|
||||||
"@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1",
|
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
|
||||||
"@ogre-tools/injectable-extension-for-mobx": "^12.0.1",
|
"@ogre-tools/injectable-extension-for-mobx": "^15.1.1",
|
||||||
"@ogre-tools/injectable-react": "^12.0.1",
|
"@ogre-tools/injectable-react": "^15.1.1",
|
||||||
"mobx": "^6.8.0",
|
"mobx": "^6.8.0",
|
||||||
"rimraf": "^4.1.2"
|
"rimraf": "^4.1.2"
|
||||||
},
|
},
|
||||||
@ -34461,7 +34469,9 @@
|
|||||||
"version": "6.4.0-beta.13",
|
"version": "6.4.0-beta.13",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"rimraf": "^4.1.2"
|
"chalk": "^5.2.0",
|
||||||
|
"inquirer": "^9.1.4",
|
||||||
|
"semver": "^7.3.8"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"create-release-pr": "dist/index.js"
|
"create-release-pr": "dist/index.js"
|
||||||
@ -34469,23 +34479,10 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@swc/cli": "^0.1.61",
|
"@swc/cli": "^0.1.61",
|
||||||
"@swc/core": "^1.3.35",
|
"@swc/core": "^1.3.35",
|
||||||
"@types/command-line-args": "^5.2.0",
|
"@types/inquirer": "^9.0.3",
|
||||||
"@types/fs-extra": "^11.0.1",
|
|
||||||
"@types/node": "^16.18.11",
|
"@types/node": "^16.18.11",
|
||||||
"@types/semver": "^7.3.13",
|
"@types/semver": "^7.3.13",
|
||||||
"command-line-args": "^5.2.1",
|
"rimraf": "^4.1.2"
|
||||||
"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": "*"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/release-tool/node_modules/@types/node": {
|
"packages/release-tool/node_modules/@types/node": {
|
||||||
@ -34494,18 +34491,293 @@
|
|||||||
"integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw==",
|
"integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"packages/release-tool/node_modules/fs-extra": {
|
"packages/release-tool/node_modules/ansi-escapes": {
|
||||||
"version": "11.1.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.0.0.tgz",
|
||||||
"integrity": "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==",
|
"integrity": "sha512-IG23inYII3dWlU2EyiAiGj6Bwal5GzsgPMwjYGvc1HPE2dgbj4ZB5ToWBKSquKw74nB3TIuOwaI6/jSULzfgrw==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"graceful-fs": "^4.2.0",
|
"type-fest": "^3.0.0"
|
||||||
"jsonfile": "^6.0.1",
|
|
||||||
"universalify": "^2.0.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"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": {
|
"packages/semver": {
|
||||||
@ -34536,10 +34808,17 @@
|
|||||||
"version": "6.4.0-beta.13",
|
"version": "6.4.0-beta.13",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ogre-tools/fp": "^12.0.1",
|
"@ogre-tools/fp": "^15.1.1",
|
||||||
"@ogre-tools/injectable": "^12.0.1",
|
"@ogre-tools/injectable": "^15.1.1",
|
||||||
"lodash": "^4.17.15"
|
"lodash": "^4.17.15"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"packages/technical-features/feature-core": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@ogre-tools/injectable": "^15.1.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,7 +57,7 @@
|
|||||||
"test:unit": "jest --testPathIgnorePatterns integration",
|
"test:unit": "jest --testPathIgnorePatterns integration",
|
||||||
"test:watch": "func() { jest ${1} --watch --testPathIgnorePatterns integration; }; func",
|
"test:watch": "func() { jest ${1} --watch --testPathIgnorePatterns integration; }; func",
|
||||||
"lint": "PROD=true eslint --ext js,ts,tsx --max-warnings=0 .",
|
"lint": "PROD=true eslint --ext js,ts,tsx --max-warnings=0 .",
|
||||||
"lint:fix": "npm run lint --fix"
|
"lint:fix": "npm run lint -- --fix"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"k8sProxyVersion": "0.3.0",
|
"k8sProxyVersion": "0.3.0",
|
||||||
@ -130,11 +130,11 @@
|
|||||||
"@k8slens/node-fetch": "^6.4.0-beta.13",
|
"@k8slens/node-fetch": "^6.4.0-beta.13",
|
||||||
"@kubernetes/client-node": "^0.18.1",
|
"@kubernetes/client-node": "^0.18.1",
|
||||||
"@material-ui/styles": "^4.11.5",
|
"@material-ui/styles": "^4.11.5",
|
||||||
"@ogre-tools/fp": "^12.0.1",
|
"@ogre-tools/fp": "^15.1.1",
|
||||||
"@ogre-tools/injectable": "^12.0.1",
|
"@ogre-tools/injectable": "^15.1.1",
|
||||||
"@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1",
|
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
|
||||||
"@ogre-tools/injectable-extension-for-mobx": "^12.0.1",
|
"@ogre-tools/injectable-extension-for-mobx": "^15.1.1",
|
||||||
"@ogre-tools/injectable-react": "^12.0.1",
|
"@ogre-tools/injectable-react": "^15.1.1",
|
||||||
"@sentry/electron": "^3.0.8",
|
"@sentry/electron": "^3.0.8",
|
||||||
"@sentry/integrations": "^6.19.3",
|
"@sentry/integrations": "^6.19.3",
|
||||||
"@side/jest-runtime": "^1.1.0",
|
"@side/jest-runtime": "^1.1.0",
|
||||||
|
|||||||
@ -74,8 +74,7 @@ describe("cluster-store", () => {
|
|||||||
di.override(kubectlBinaryNameInjectable, () => "kubectl");
|
di.override(kubectlBinaryNameInjectable, () => "kubectl");
|
||||||
di.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
|
di.override(kubectlDownloadingNormalizedArchInjectable, () => "amd64");
|
||||||
di.override(normalizedPlatformInjectable, () => "darwin");
|
di.override(normalizedPlatformInjectable, () => "darwin");
|
||||||
createCluster = di.inject(createClusterInjectionToken);
|
|
||||||
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
|
|
||||||
writeJsonSync = di.inject(writeJsonSyncInjectable);
|
writeJsonSync = di.inject(writeJsonSyncInjectable);
|
||||||
writeFileSync = di.inject(writeFileSyncInjectable);
|
writeFileSync = di.inject(writeFileSyncInjectable);
|
||||||
writeBufferSync = di.inject(writeBufferSyncInjectable);
|
writeBufferSync = di.inject(writeBufferSyncInjectable);
|
||||||
@ -85,6 +84,9 @@ describe("cluster-store", () => {
|
|||||||
|
|
||||||
describe("empty config", () => {
|
describe("empty config", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
|
createCluster = di.inject(createClusterInjectionToken);
|
||||||
|
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
|
||||||
|
|
||||||
writeJsonSync("/some-directory-for-user-data/lens-cluster-store.json", {});
|
writeJsonSync("/some-directory-for-user-data/lens-cluster-store.json", {});
|
||||||
clusterStore = di.inject(clusterStoreInjectable);
|
clusterStore = di.inject(clusterStoreInjectable);
|
||||||
clusterStore.load();
|
clusterStore.load();
|
||||||
@ -198,6 +200,10 @@ describe("cluster-store", () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
createCluster = di.inject(createClusterInjectionToken);
|
||||||
|
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
|
||||||
|
|
||||||
clusterStore = di.inject(clusterStoreInjectable);
|
clusterStore = di.inject(clusterStoreInjectable);
|
||||||
clusterStore.load();
|
clusterStore.load();
|
||||||
});
|
});
|
||||||
@ -249,6 +255,10 @@ describe("cluster-store", () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
createCluster = di.inject(createClusterInjectionToken);
|
||||||
|
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
|
||||||
|
|
||||||
clusterStore = di.inject(clusterStoreInjectable);
|
clusterStore = di.inject(clusterStoreInjectable);
|
||||||
clusterStore.load();
|
clusterStore.load();
|
||||||
});
|
});
|
||||||
@ -262,6 +272,11 @@ describe("cluster-store", () => {
|
|||||||
|
|
||||||
describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
|
describe("pre 3.6.0-beta.1 config with an existing cluster", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
di.override(clusterStoreMigrationVersionInjectable, () => "3.6.0");
|
||||||
|
|
||||||
|
createCluster = di.inject(createClusterInjectionToken);
|
||||||
|
getCustomKubeConfigFilePath = di.inject(getCustomKubeConfigFilePathInjectable);
|
||||||
|
|
||||||
writeJsonSync("/some-directory-for-user-data/lens-cluster-store.json", {
|
writeJsonSync("/some-directory-for-user-data/lens-cluster-store.json", {
|
||||||
__internal__: {
|
__internal__: {
|
||||||
migrations: {
|
migrations: {
|
||||||
@ -281,8 +296,6 @@ describe("cluster-store", () => {
|
|||||||
});
|
});
|
||||||
writeBufferSync("/some-directory-for-user-data/icon_path", testDataIcon);
|
writeBufferSync("/some-directory-for-user-data/icon_path", testDataIcon);
|
||||||
|
|
||||||
di.override(clusterStoreMigrationVersionInjectable, () => "3.6.0");
|
|
||||||
|
|
||||||
clusterStore = di.inject(clusterStoreInjectable);
|
clusterStore = di.inject(clusterStoreInjectable);
|
||||||
clusterStore.load();
|
clusterStore.load();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -30,9 +30,9 @@ describe("user store tests", () => {
|
|||||||
get: () => "latest" as const,
|
get: () => "latest" as const,
|
||||||
init: async () => {},
|
init: async () => {},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
await di.inject(defaultUpdateChannelInjectable).init();
|
await di.inject(defaultUpdateChannelInjectable).init();
|
||||||
|
|
||||||
userStore = di.inject(userStoreInjectable);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("for an empty config", () => {
|
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/lens-user-store.json", {});
|
||||||
writeJsonSync("/some-directory-for-user-data/kube_config", {});
|
writeJsonSync("/some-directory-for-user-data/kube_config", {});
|
||||||
|
|
||||||
|
userStore = di.inject(userStoreInjectable);
|
||||||
|
|
||||||
userStore.load();
|
userStore.load();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -90,6 +92,8 @@ describe("user store tests", () => {
|
|||||||
|
|
||||||
di.override(userStoreMigrationVersionInjectable, () => "10.0.0");
|
di.override(userStoreMigrationVersionInjectable, () => "10.0.0");
|
||||||
|
|
||||||
|
userStore = di.inject(userStoreInjectable);
|
||||||
|
|
||||||
userStore.load();
|
userStore.load();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { DiContainer } from "@ogre-tools/injectable";
|
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 clusterFrameContextForNamespacedResourcesInjectable from "../../../renderer/cluster-frame-context/for-namespaced-resources.injectable";
|
||||||
import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
|
import hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
|
||||||
import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
|
import { getDiForUnitTesting } from "../../../renderer/getDiForUnitTesting";
|
||||||
@ -18,6 +17,7 @@ import { KubeApi } from "../kube-api";
|
|||||||
import { KubeObject } from "../kube-object";
|
import { KubeObject } from "../kube-object";
|
||||||
import { KubeObjectStore } from "../kube-object.store";
|
import { KubeObjectStore } from "../kube-object.store";
|
||||||
import maybeKubeApiInjectable from "../maybe-kube-api.injectable";
|
import maybeKubeApiInjectable from "../maybe-kube-api.injectable";
|
||||||
|
import { createClusterInjectionToken } from "../../cluster/create-cluster-injection-token";
|
||||||
|
|
||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { KubeApi as ExternalKubeApi } from "../../../extensions/common-api/k8s-api";
|
import { KubeApi as ExternalKubeApi } from "../../../extensions/common-api/k8s-api";
|
||||||
@ -43,7 +43,7 @@ describe("ApiManager", () => {
|
|||||||
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
||||||
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||||
|
|
||||||
const createCluster = di.inject(createClusterInjectable);
|
const createCluster = di.inject(createClusterInjectionToken);
|
||||||
|
|
||||||
di.override(hostedClusterInjectable, () => createCluster({
|
di.override(hostedClusterInjectable, () => createCluster({
|
||||||
contextName: "some-context-name",
|
contextName: "some-context-name",
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import setupAutoRegistrationInjectable from "../../../renderer/before-frame-star
|
|||||||
import { createMockResponseFromString } from "../../../test-utils/mock-responses";
|
import { createMockResponseFromString } from "../../../test-utils/mock-responses";
|
||||||
import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
|
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 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 hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
|
||||||
import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
||||||
import apiManagerInjectable from "../api-manager/manager.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 ingressApiInjectable from "../endpoints/ingress.api.injectable";
|
||||||
import loggerInjectable from "../../logger.injectable";
|
import loggerInjectable from "../../logger.injectable";
|
||||||
import maybeKubeApiInjectable from "../maybe-kube-api.injectable";
|
import maybeKubeApiInjectable from "../maybe-kube-api.injectable";
|
||||||
|
import { createClusterInjectionToken } from "../../cluster/create-cluster-injection-token";
|
||||||
|
|
||||||
describe("KubeApi", () => {
|
describe("KubeApi", () => {
|
||||||
let fetchMock: AsyncFnMock<Fetch>;
|
let fetchMock: AsyncFnMock<Fetch>;
|
||||||
@ -39,7 +39,7 @@ describe("KubeApi", () => {
|
|||||||
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
||||||
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||||
|
|
||||||
const createCluster = di.inject(createClusterInjectable);
|
const createCluster = di.inject(createClusterInjectionToken);
|
||||||
|
|
||||||
di.override(hostedClusterInjectable, () => createCluster({
|
di.override(hostedClusterInjectable, () => createCluster({
|
||||||
contextName: "some-context-name",
|
contextName: "some-context-name",
|
||||||
|
|||||||
@ -24,7 +24,6 @@ import setupAutoRegistrationInjectable from "../../../renderer/before-frame-star
|
|||||||
import { createMockResponseFromStream, createMockResponseFromString } from "../../../test-utils/mock-responses";
|
import { createMockResponseFromStream, createMockResponseFromString } from "../../../test-utils/mock-responses";
|
||||||
import storesAndApisCanBeCreatedInjectable from "../../../renderer/stores-apis-can-be-created.injectable";
|
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 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 hostedClusterInjectable from "../../../renderer/cluster-frame-context/hosted-cluster.injectable";
|
||||||
import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
import directoryForKubeConfigsInjectable from "../../app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
||||||
import apiKubeInjectable from "../../../renderer/k8s/api-kube.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
|
// NOTE: this is fine because we are testing something that only exported
|
||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { PodsApi } from "../../../extensions/common-api/k8s-api";
|
import { PodsApi } from "../../../extensions/common-api/k8s-api";
|
||||||
|
import { createClusterInjectionToken } from "../../cluster/create-cluster-injection-token";
|
||||||
|
|
||||||
describe("createKubeApiForRemoteCluster", () => {
|
describe("createKubeApiForRemoteCluster", () => {
|
||||||
let createKubeApiForRemoteCluster: CreateKubeApiForRemoteCluster;
|
let createKubeApiForRemoteCluster: CreateKubeApiForRemoteCluster;
|
||||||
@ -48,7 +48,7 @@ describe("createKubeApiForRemoteCluster", () => {
|
|||||||
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
||||||
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||||
|
|
||||||
const createCluster = di.inject(createClusterInjectable);
|
const createCluster = di.inject(createClusterInjectionToken);
|
||||||
|
|
||||||
di.override(hostedClusterInjectable, () => createCluster({
|
di.override(hostedClusterInjectable, () => createCluster({
|
||||||
contextName: "some-context-name",
|
contextName: "some-context-name",
|
||||||
@ -154,7 +154,7 @@ describe("KubeApi", () => {
|
|||||||
fetchMock = asyncFn();
|
fetchMock = asyncFn();
|
||||||
di.override(fetchInjectable, () => fetchMock);
|
di.override(fetchInjectable, () => fetchMock);
|
||||||
|
|
||||||
const createCluster = di.inject(createClusterInjectable);
|
const createCluster = di.inject(createClusterInjectionToken);
|
||||||
const createKubeJsonApi = di.inject(createKubeJsonApiInjectable);
|
const createKubeJsonApi = di.inject(createKubeJsonApiInjectable);
|
||||||
|
|
||||||
di.override(hostedClusterInjectable, () => createCluster({
|
di.override(hostedClusterInjectable, () => createCluster({
|
||||||
|
|||||||
@ -51,7 +51,7 @@ export class ResourceStack {
|
|||||||
|
|
||||||
this.dependencies.logger.warn(`[RESOURCE-STACK]: failed to apply resources: ${result.error}`);
|
this.dependencies.logger.warn(`[RESOURCE-STACK]: failed to apply resources: ${result.error}`);
|
||||||
|
|
||||||
return "";
|
throw new Error(result.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -3,13 +3,20 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import { createLogger, format } from "winston";
|
||||||
import type { Logger } from "./logger";
|
import type { Logger } from "./logger";
|
||||||
import winstonLoggerInjectable from "./winston-logger.injectable";
|
import { loggerTransportInjectionToken } from "./logger/transports";
|
||||||
|
|
||||||
const loggerInjectable = getInjectable({
|
const loggerInjectable = getInjectable({
|
||||||
id: "logger",
|
id: "logger",
|
||||||
instantiate: (di): Logger => {
|
instantiate: (di): Logger => {
|
||||||
const baseLogger = di.inject(winstonLoggerInjectable);
|
const baseLogger = createLogger({
|
||||||
|
format: format.combine(
|
||||||
|
format.splat(),
|
||||||
|
format.simple(),
|
||||||
|
),
|
||||||
|
transports: di.injectMany(loggerTransportInjectionToken),
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
debug: (message, ...data) => baseLogger.debug(message, ...data),
|
debug: (message, ...data) => baseLogger.debug(message, ...data),
|
||||||
|
|||||||
@ -19,7 +19,10 @@ import asyncFn from "@async-fn/jest";
|
|||||||
import { getPromiseStatus } from "../../test-utils/get-promise-status";
|
import { getPromiseStatus } from "../../test-utils/get-promise-status";
|
||||||
import { runInAction } from "mobx";
|
import { runInAction } from "mobx";
|
||||||
import type { RequestChannelHandler } from "../../../main/utils/channel/channel-listeners/listener-tokens";
|
import 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 TestMessageChannel = MessageChannel<string>;
|
||||||
type TestRequestChannel = RequestChannel<string, string>;
|
type TestRequestChannel = RequestChannel<string, string>;
|
||||||
@ -199,21 +202,32 @@ describe("channel", () => {
|
|||||||
it("when registering multiple handlers for the same channel, throws", async () => {
|
it("when registering multiple handlers for the same channel, throws", async () => {
|
||||||
const applicationBuilder = getApplicationBuilder();
|
const applicationBuilder = getApplicationBuilder();
|
||||||
|
|
||||||
const testChannelListenerInMainInjectable = getRequestChannelListenerInjectable({
|
const someChannelListenerInjectable = getInjectable({
|
||||||
channel: testRequestChannel,
|
id: "some-channel-listener",
|
||||||
handler: () => () => "some-value",
|
|
||||||
});
|
instantiate: () => ({
|
||||||
const testChannelListenerInMain2Injectable = getRequestChannelListenerInjectable({
|
channel: testRequestChannel,
|
||||||
channel: testRequestChannel,
|
handler: () => () => "irrelevant",
|
||||||
handler: () => () => "some-other-value",
|
}),
|
||||||
|
|
||||||
|
injectionToken: requestChannelListenerInjectionToken,
|
||||||
});
|
});
|
||||||
|
|
||||||
testChannelListenerInMain2Injectable.id += "2";
|
const someOtherChannelListenerInjectable = getInjectable({
|
||||||
|
id: "some-other-channel-listener",
|
||||||
|
|
||||||
|
instantiate: () => ({
|
||||||
|
channel: testRequestChannel,
|
||||||
|
handler: () => () => "irrelevant",
|
||||||
|
}),
|
||||||
|
|
||||||
|
injectionToken: requestChannelListenerInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
applicationBuilder.beforeApplicationStart((mainDi) => {
|
applicationBuilder.beforeApplicationStart((mainDi) => {
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
mainDi.register(testChannelListenerInMainInjectable);
|
mainDi.register(someChannelListenerInjectable);
|
||||||
mainDi.register(testChannelListenerInMain2Injectable);
|
mainDi.register(someOtherChannelListenerInjectable);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ const withOrphanPromiseInjectable = getInjectable({
|
|||||||
toBeDecorated,
|
toBeDecorated,
|
||||||
withErrorLoggingFor(() => "Orphan promise rejection encountered"),
|
withErrorLoggingFor(() => "Orphan promise rejection encountered"),
|
||||||
withErrorSuppression,
|
withErrorSuppression,
|
||||||
);
|
) as ((...args: any[]) => any);
|
||||||
|
|
||||||
decorated(...args);
|
decorated(...args);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -18,6 +18,6 @@ export const apiKubePrefix = "/api-kube"; // k8s cluster apis
|
|||||||
|
|
||||||
// Links
|
// Links
|
||||||
export const issuesTrackerUrl = "https://github.com/lensapp/lens/issues" as string;
|
export const issuesTrackerUrl = "https://github.com/lensapp/lens/issues" as string;
|
||||||
export const slackUrl = "https://k8slens.dev/slack.html" as string;
|
|
||||||
export const supportUrl = "https://docs.k8slens.dev/support/" as string;
|
export const supportUrl = "https://docs.k8slens.dev/support/" as string;
|
||||||
export const docsUrl = "https://docs.k8slens.dev" as string;
|
export const docsUrl = "https://docs.k8slens.dev" as string;
|
||||||
|
export const forumsUrl = "https://forums.k8slens.dev" as string;
|
||||||
|
|||||||
@ -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;
|
|
||||||
@ -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 { 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 { 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 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 { 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 { asLegacyGlobalForExtensionApi } from "../as-legacy-globals-for-extension-api/as-legacy-global-object-for-extension-api";
|
||||||
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
import userStoreInjectable from "../../common/user-store/user-store.injectable";
|
||||||
@ -53,6 +53,9 @@ export const App = {
|
|||||||
|
|
||||||
return di.inject(isLinuxInjectable);
|
return di.inject(isLinuxInjectable);
|
||||||
},
|
},
|
||||||
slackUrl,
|
/**
|
||||||
|
* @deprecated This value is now `""` and is left here for backwards compatability.
|
||||||
|
*/
|
||||||
|
slackUrl: "",
|
||||||
issuesTrackerUrl,
|
issuesTrackerUrl,
|
||||||
} as const;
|
} as const;
|
||||||
|
|||||||
@ -107,11 +107,11 @@ exports[`extension special characters in page registrations renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -107,11 +107,11 @@ exports[`navigate to extension page renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -107,11 +107,11 @@ exports[`add-cluster - navigation using application menu renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -108,11 +108,11 @@ exports[`installing update when started renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -413,11 +413,11 @@ exports[`installing update when started when user checks for updates renders 1`]
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -718,11 +718,11 @@ exports[`installing update when started when user checks for updates when new up
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1048,11 +1048,11 @@ exports[`installing update when started when user checks for updates when new up
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1378,11 +1378,11 @@ exports[`installing update when started when user checks for updates when new up
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1683,11 +1683,11 @@ exports[`installing update when started when user checks for updates when no new
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -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
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -438,11 +438,11 @@ exports[`encourage user to update when sufficient time passed since update was d
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -108,11 +108,11 @@ exports[`installing update using tray when started renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -413,11 +413,11 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -718,11 +718,11 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1048,11 +1048,11 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1378,11 +1378,11 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1683,11 +1683,11 @@ exports[`installing update using tray when started when user checks for updates
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -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
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -463,11 +463,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
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -840,11 +840,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
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -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
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -108,11 +108,11 @@ exports[`selection of update stability when started renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -108,11 +108,11 @@ exports[`opening catalog entity details panel renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -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
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -595,11 +595,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing ESC
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -991,11 +991,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing SHI
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1531,11 +1531,11 @@ exports[`Command Pallet: keyboard shortcut tests when on linux when pressing SHI
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1836,11 +1836,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -2141,11 +2141,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing ESC
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -2446,11 +2446,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing SHI
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -2847,11 +2847,11 @@ exports[`Command Pallet: keyboard shortcut tests when on macOS when pressing SHI
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -108,11 +108,11 @@ exports[`Showing correct entity settings renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -894,7 +894,40 @@ exports[`Showing correct entity settings when navigating to non-local cluster en
|
|||||||
>
|
>
|
||||||
Proxy
|
Proxy
|
||||||
</h2>
|
</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>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -107,11 +107,11 @@ exports[`extensions - navigation using application menu renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -107,11 +107,11 @@ exports[`preferences - navigation using application menu renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -108,11 +108,11 @@ exports[`show-about-using-tray renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -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
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -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
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -422,11 +422,11 @@ exports[`extendability-using-extension-api given an extension with top-bar items
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -727,11 +727,11 @@ exports[`extendability-using-extension-api given an extension with top-bar items
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1032,11 +1032,11 @@ exports[`extendability-using-extension-api renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -107,11 +107,11 @@ exports[`welcome - navigation using application menu renders 1`] = `
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
@ -1182,11 +1182,11 @@ exports[`welcome - navigation using application menu when navigated somewhere el
|
|||||||
If you have any questions or feedback, please join our
|
If you have any questions or feedback, please join our
|
||||||
<a
|
<a
|
||||||
class="link"
|
class="link"
|
||||||
href="https://k8slens.dev/slack.html"
|
href="https://forums.k8slens.dev"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -16,7 +16,8 @@ export function registerInjectables(di: DiContainer) {
|
|||||||
|
|
||||||
autoRegister({
|
autoRegister({
|
||||||
di,
|
di,
|
||||||
requireContexts: [
|
targetModule: module,
|
||||||
|
getRequireContexts: () => [
|
||||||
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
|
|||||||
@ -10,8 +10,8 @@ export const lensWebsiteLinkName = "Lens Website";
|
|||||||
export const lensDocumentationWeblinkId = "lens-documentation-link";
|
export const lensDocumentationWeblinkId = "lens-documentation-link";
|
||||||
export const lensDocumentationWeblinkName = "Lens Documentation";
|
export const lensDocumentationWeblinkName = "Lens Documentation";
|
||||||
|
|
||||||
export const lensSlackWeblinkId = "lens-slack-link";
|
export const lensForumsWeblinkId = "lens-forums-link";
|
||||||
export const lensSlackWeblinkName = "Lens Community Slack";
|
export const lensForumsWeblinkName = "Lens Forums";
|
||||||
|
|
||||||
export const lensTwitterWeblinkId = "lens-twitter-link";
|
export const lensTwitterWeblinkId = "lens-twitter-link";
|
||||||
export const lensTwitterWeblinkName = "Lens on Twitter";
|
export const lensTwitterWeblinkName = "Lens on Twitter";
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { docsUrl, slackUrl } from "../../../common/vars";
|
import { docsUrl, forumsUrl } from "../../../common/vars";
|
||||||
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
|
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
|
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
|
||||||
@ -20,7 +20,7 @@ const v514WeblinkStoreMigrationInjectable = getInjectable({
|
|||||||
weblinks.push(
|
weblinks.push(
|
||||||
{ id: "https://k8slens.dev", name: links.lensWebsiteLinkName, url: "https://k8slens.dev" },
|
{ id: "https://k8slens.dev", name: links.lensWebsiteLinkName, url: "https://k8slens.dev" },
|
||||||
{ id: docsUrl, name: links.lensDocumentationWeblinkName, url: docsUrl },
|
{ 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://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://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/" },
|
{ id: "https://kubernetes.io/docs/home/", name: links.kubernetesDocumentationWeblinkName, url: "https://kubernetes.io/docs/home/" },
|
||||||
|
|||||||
@ -16,40 +16,40 @@ const v545Beta1WeblinkStoreMigrationInjectable = getInjectable({
|
|||||||
const weblinksRaw = store.get("weblinks");
|
const weblinksRaw = store.get("weblinks");
|
||||||
const weblinks = (Array.isArray(weblinksRaw) ? weblinksRaw : []) as WeblinkData[];
|
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) {
|
if (lensWebsite) {
|
||||||
lensWebsiteLink.id = links.lensWebsiteWeblinkId;
|
lensWebsite.id = links.lensWebsiteWeblinkId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lensDocumentationWeblinkLink = weblinks.find(weblink => weblink.name === links.lensDocumentationWeblinkName);
|
const lensDocumentationWeblink = weblinks.find(weblink => weblink.name === links.lensDocumentationWeblinkName);
|
||||||
|
|
||||||
if (lensDocumentationWeblinkLink) {
|
if (lensDocumentationWeblink) {
|
||||||
lensDocumentationWeblinkLink.id = links.lensDocumentationWeblinkId;
|
lensDocumentationWeblink.id = links.lensDocumentationWeblinkId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lensSlackWeblinkLink = weblinks.find(weblink => weblink.name === links.lensSlackWeblinkName);
|
const lensForumsWeblink = weblinks.find(weblink => weblink.name === links.lensForumsWeblinkName);
|
||||||
|
|
||||||
if (lensSlackWeblinkLink) {
|
if (lensForumsWeblink) {
|
||||||
lensSlackWeblinkLink.id = links.lensSlackWeblinkId;
|
lensForumsWeblink.id = links.lensForumsWeblinkId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lensTwitterWeblinkLink = weblinks.find(weblink => weblink.name === links.lensTwitterWeblinkName);
|
const lensTwitterWeblink = weblinks.find(weblink => weblink.name === links.lensTwitterWeblinkName);
|
||||||
|
|
||||||
if (lensTwitterWeblinkLink) {
|
if (lensTwitterWeblink) {
|
||||||
lensTwitterWeblinkLink.id = links.lensTwitterWeblinkId;
|
lensTwitterWeblink.id = links.lensTwitterWeblinkId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const lensBlogWeblinkLink = weblinks.find(weblink => weblink.name === links.lensBlogWeblinkName);
|
const lensBlogWeblink = weblinks.find(weblink => weblink.name === links.lensBlogWeblinkName);
|
||||||
|
|
||||||
if (lensBlogWeblinkLink) {
|
if (lensBlogWeblink) {
|
||||||
lensBlogWeblinkLink.id = links.lensBlogWeblinkId;
|
lensBlogWeblink.id = links.lensBlogWeblinkId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const kubernetesDocumentationWeblinkLink = weblinks.find(weblink => weblink.name === links.kubernetesDocumentationWeblinkName);
|
const kubernetesDocumentationWeblink = weblinks.find(weblink => weblink.name === links.kubernetesDocumentationWeblinkName);
|
||||||
|
|
||||||
if (kubernetesDocumentationWeblinkLink) {
|
if (kubernetesDocumentationWeblink) {
|
||||||
kubernetesDocumentationWeblinkLink.id = links.kubernetesDocumentationWeblinkId;
|
kubernetesDocumentationWeblink.id = links.kubernetesDocumentationWeblinkId;
|
||||||
}
|
}
|
||||||
|
|
||||||
store.set("weblinks", weblinks);
|
store.set("weblinks", weblinks);
|
||||||
|
|||||||
@ -3,11 +3,11 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { docsUrl, slackUrl } from "../../../common/vars";
|
import { docsUrl, forumsUrl } from "../../../common/vars";
|
||||||
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
|
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
|
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
|
||||||
import { lensDocumentationWeblinkId, lensSlackWeblinkId } from "../links";
|
import { lensDocumentationWeblinkId, lensForumsWeblinkId } from "../links";
|
||||||
import { applicationInformationToken } from "@k8slens/application";
|
import { applicationInformationToken } from "@k8slens/application";
|
||||||
|
|
||||||
const currentVersionWeblinkStoreMigrationInjectable = getInjectable({
|
const currentVersionWeblinkStoreMigrationInjectable = getInjectable({
|
||||||
@ -20,10 +20,10 @@ const currentVersionWeblinkStoreMigrationInjectable = getInjectable({
|
|||||||
run(store) {
|
run(store) {
|
||||||
const weblinksRaw = store.get("weblinks");
|
const weblinksRaw = store.get("weblinks");
|
||||||
const weblinks = (Array.isArray(weblinksRaw) ? weblinksRaw : []) as WeblinkData[];
|
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) {
|
if (forumsWeblink) {
|
||||||
slackWeblink.url = slackUrl;
|
forumsWeblink.url = forumsUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const docsWeblink = weblinks.find(weblink => weblink.id === lensDocumentationWeblinkId);
|
const docsWeblink = weblinks.find(weblink => weblink.id === lensDocumentationWeblinkId);
|
||||||
@ -32,7 +32,9 @@ const currentVersionWeblinkStoreMigrationInjectable = getInjectable({
|
|||||||
docsWeblink.url = docsUrl;
|
docsWeblink.url = docsUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
store.set("weblinks", weblinks);
|
const removedSlackLink = weblinks.filter(weblink => weblink.id !== "lens-slack-link");
|
||||||
|
|
||||||
|
store.set("weblinks", removedSlackLink);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@ -46,9 +46,7 @@ export async function bootstrap(di: DiContainer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await initializeApp(() => {
|
await initializeApp(() => unmountComponentAtNode(rootElem));
|
||||||
unmountComponentAtNode(rootElem);
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`[BOOTSTRAP]: view initialization error: ${error}`, {
|
console.error(`[BOOTSTRAP]: view initialization error: ${error}`, {
|
||||||
origin: location.href,
|
origin: location.href,
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import type { IComputedValue } from "mobx";
|
|||||||
import type { CarouselProps } from "react-material-ui-carousel";
|
import type { CarouselProps } from "react-material-ui-carousel";
|
||||||
import LegacyCarousel from "react-material-ui-carousel";
|
import LegacyCarousel from "react-material-ui-carousel";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { slackUrl } from "../../../common/vars";
|
import { forumsUrl } from "../../../common/vars";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
import welcomeMenuItemsInjectable from "./welcome-menu-items/welcome-menu-items.injectable";
|
import welcomeMenuItemsInjectable from "./welcome-menu-items/welcome-menu-items.injectable";
|
||||||
import type { WelcomeMenuRegistration } from "./welcome-menu-items/welcome-menu-registration";
|
import type { WelcomeMenuRegistration } from "./welcome-menu-items/welcome-menu-registration";
|
||||||
@ -93,12 +93,12 @@ const NonInjectedWelcome = observer(({
|
|||||||
<br />
|
<br />
|
||||||
{"If you have any questions or feedback, please join our "}
|
{"If you have any questions or feedback, please join our "}
|
||||||
<a
|
<a
|
||||||
href={slackUrl}
|
href={forumsUrl}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="link"
|
className="link"
|
||||||
>
|
>
|
||||||
Lens Community slack channel
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
.
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import type { ErrorInfo } from "react";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
import { issuesTrackerUrl, slackUrl } from "../../../common/vars";
|
import { issuesTrackerUrl, forumsUrl } from "../../../common/vars";
|
||||||
import type { SingleOrMany } from "../../utils";
|
import type { SingleOrMany } from "../../utils";
|
||||||
import type { ObservableHistory } from "mobx-observable-history";
|
import type { ObservableHistory } from "mobx-observable-history";
|
||||||
import { withInjectables } from "@ogre-tools/injectable-react";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
@ -53,15 +53,15 @@ class NonInjectedErrorBoundary extends React.Component<ErrorBoundaryProps & Depe
|
|||||||
</h5>
|
</h5>
|
||||||
<p>
|
<p>
|
||||||
|
|
||||||
{"To help us improve the product please report bugs to "}
|
{"To help us improve the product please report bugs on"}
|
||||||
<a
|
<a
|
||||||
href={slackUrl}
|
href={forumsUrl}
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Slack
|
Lens Forums
|
||||||
</a>
|
</a>
|
||||||
{" community or "}
|
{" or on our"}
|
||||||
<a
|
<a
|
||||||
href={issuesTrackerUrl}
|
href={issuesTrackerUrl}
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
|
|||||||
@ -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 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 directoryForKubeConfigsInjectable from "../../../common/app-paths/directory-for-kube-configs/directory-for-kube-configs.injectable";
|
||||||
import hostedClusterInjectable from "../../cluster-frame-context/hosted-cluster.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 type { PodStore } from "../+workloads-pods/store";
|
||||||
|
import { createClusterInjectionToken } from "../../../common/cluster/create-cluster-injection-token";
|
||||||
|
|
||||||
describe("kube-object-list-layout", () => {
|
describe("kube-object-list-layout", () => {
|
||||||
let di: DiContainer;
|
let di: DiContainer;
|
||||||
@ -34,7 +34,7 @@ describe("kube-object-list-layout", () => {
|
|||||||
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
di.override(directoryForKubeConfigsInjectable, () => "/some-kube-configs");
|
||||||
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
di.override(storesAndApisCanBeCreatedInjectable, () => true);
|
||||||
|
|
||||||
const createCluster = di.inject(createClusterInjectable);
|
const createCluster = di.inject(createClusterInjectionToken);
|
||||||
|
|
||||||
di.override(hostedClusterInjectable, () => createCluster({
|
di.override(hostedClusterInjectable, () => createCluster({
|
||||||
contextName: "some-context-name",
|
contextName: "some-context-name",
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import emitAppEventInjectable from "../../../../common/app-event-bus/emit-event.
|
|||||||
import loadExtensionsInjectable from "../../load-extensions.injectable";
|
import loadExtensionsInjectable from "../../load-extensions.injectable";
|
||||||
import loggerInjectable from "../../../../common/logger.injectable";
|
import loggerInjectable from "../../../../common/logger.injectable";
|
||||||
import showErrorNotificationInjectable from "../../../components/notifications/show-error-notification.injectable";
|
import showErrorNotificationInjectable from "../../../components/notifications/show-error-notification.injectable";
|
||||||
import closeRendererLogFileInjectable from "../../../logger/close-renderer-log-file.injectable";
|
|
||||||
|
|
||||||
const initClusterFrameInjectable = getInjectable({
|
const initClusterFrameInjectable = getInjectable({
|
||||||
id: "init-cluster-frame",
|
id: "init-cluster-frame",
|
||||||
@ -30,7 +29,6 @@ const initClusterFrameInjectable = getInjectable({
|
|||||||
emitAppEvent: di.inject(emitAppEventInjectable),
|
emitAppEvent: di.inject(emitAppEventInjectable),
|
||||||
logger: di.inject(loggerInjectable),
|
logger: di.inject(loggerInjectable),
|
||||||
showErrorNotification: di.inject(showErrorNotificationInjectable),
|
showErrorNotification: di.inject(showErrorNotificationInjectable),
|
||||||
closeFileLogging: di.inject(closeRendererLogFileInjectable),
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import { once } from "lodash";
|
|
||||||
import type { Cluster } from "../../../../common/cluster/cluster";
|
import type { Cluster } from "../../../../common/cluster/cluster";
|
||||||
import type { CatalogEntityRegistry } from "../../../api/catalog/entity/registry";
|
import type { CatalogEntityRegistry } from "../../../api/catalog/entity/registry";
|
||||||
import type { ShowNotification } from "../../../components/notifications";
|
import type { ShowNotification } from "../../../components/notifications";
|
||||||
@ -19,7 +18,6 @@ interface Dependencies {
|
|||||||
emitAppEvent: EmitAppEvent;
|
emitAppEvent: EmitAppEvent;
|
||||||
logger: Logger;
|
logger: Logger;
|
||||||
showErrorNotification: ShowNotification;
|
showErrorNotification: ShowNotification;
|
||||||
closeFileLogging: () => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const logPrefix = "[CLUSTER-FRAME]:";
|
const logPrefix = "[CLUSTER-FRAME]:";
|
||||||
@ -32,7 +30,6 @@ export const initClusterFrame = ({
|
|||||||
emitAppEvent,
|
emitAppEvent,
|
||||||
logger,
|
logger,
|
||||||
showErrorNotification,
|
showErrorNotification,
|
||||||
closeFileLogging,
|
|
||||||
}: Dependencies) =>
|
}: Dependencies) =>
|
||||||
async (unmountRoot: () => void) => {
|
async (unmountRoot: () => void) => {
|
||||||
await requestSetClusterFrameId(hostedCluster.id);
|
await requestSetClusterFrameId(hostedCluster.id);
|
||||||
@ -72,14 +69,11 @@ export const initClusterFrame = ({
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const onCloseFrame = once(() => {
|
window.onbeforeunload = () => {
|
||||||
logger.info(
|
logger.info(
|
||||||
`${logPrefix} Unload dashboard, clusterId=${(hostedCluster.id)}, frameId=${frameRoutingId}`,
|
`${logPrefix} Unload dashboard, clusterId=${(hostedCluster.id)}, frameId=${frameRoutingId}`,
|
||||||
);
|
);
|
||||||
closeFileLogging();
|
|
||||||
unmountRoot();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.addEventListener("beforeunload", onCloseFrame);
|
unmountRoot();
|
||||||
window.addEventListener("pagehide", onCloseFrame);
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import loggerInjectable from "../../../common/logger.injectable";
|
|||||||
import { delay } from "../../../common/utils";
|
import { delay } from "../../../common/utils";
|
||||||
import { broadcastMessage } from "../../../common/ipc";
|
import { broadcastMessage } from "../../../common/ipc";
|
||||||
import { bundledExtensionsLoaded } from "../../../common/ipc/extension-handling";
|
import { bundledExtensionsLoaded } from "../../../common/ipc/extension-handling";
|
||||||
import closeRendererLogFileInjectable from "../../logger/close-renderer-log-file.injectable";
|
|
||||||
|
|
||||||
const initRootFrameInjectable = getInjectable({
|
const initRootFrameInjectable = getInjectable({
|
||||||
id: "init-root-frame",
|
id: "init-root-frame",
|
||||||
@ -23,7 +22,6 @@ const initRootFrameInjectable = getInjectable({
|
|||||||
const bindProtocolAddRouteHandlers = di.inject(bindProtocolAddRouteHandlersInjectable);
|
const bindProtocolAddRouteHandlers = di.inject(bindProtocolAddRouteHandlersInjectable);
|
||||||
const lensProtocolRouterRenderer = di.inject(lensProtocolRouterRendererInjectable);
|
const lensProtocolRouterRenderer = di.inject(lensProtocolRouterRendererInjectable);
|
||||||
const logger = di.inject(loggerInjectable);
|
const logger = di.inject(loggerInjectable);
|
||||||
const closeRendererLogFile = di.inject(closeRendererLogFileInjectable);
|
|
||||||
|
|
||||||
return async (unmountRoot: () => void) => {
|
return async (unmountRoot: () => void) => {
|
||||||
try {
|
try {
|
||||||
@ -57,7 +55,7 @@ const initRootFrameInjectable = getInjectable({
|
|||||||
|
|
||||||
window.addEventListener("beforeunload", () => {
|
window.addEventListener("beforeunload", () => {
|
||||||
logger.info("[ROOT-FRAME]: Unload app");
|
logger.info("[ROOT-FRAME]: Unload app");
|
||||||
closeRendererLogFile();
|
|
||||||
unmountRoot();
|
unmountRoot();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import legacyOnChannelListenInjectable from "./ipc/legacy-channel-listen.injecta
|
|||||||
import type { GlobalOverride } from "../common/test-utils/get-global-override";
|
import type { GlobalOverride } from "../common/test-utils/get-global-override";
|
||||||
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
|
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
|
||||||
import { applicationInformationFakeInjectable } from "../common/vars/application-information-fake-injectable";
|
import { applicationInformationFakeInjectable } from "../common/vars/application-information-fake-injectable";
|
||||||
|
import { registerInjectableReact } from "@ogre-tools/injectable-react";
|
||||||
|
|
||||||
export const getDiForUnitTesting = (
|
export const getDiForUnitTesting = (
|
||||||
opts: { doGeneralOverrides?: boolean } = {},
|
opts: { doGeneralOverrides?: boolean } = {},
|
||||||
@ -46,6 +47,7 @@ export const getDiForUnitTesting = (
|
|||||||
) as Injectable<any, any, any>[];
|
) as Injectable<any, any, any>[];
|
||||||
|
|
||||||
registerMobX(di);
|
registerMobX(di);
|
||||||
|
registerInjectableReact(di);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
di.register(applicationInformationFakeInjectable);
|
di.register(applicationInformationFakeInjectable);
|
||||||
|
|||||||
@ -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;
|
|
||||||
@ -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;
|
|
||||||
@ -6,18 +6,22 @@
|
|||||||
import type { DiContainer } from "@ogre-tools/injectable";
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
|
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
|
||||||
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
|
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
|
||||||
|
import { registerInjectableReact } from "@ogre-tools/injectable-react";
|
||||||
import { runInAction } from "mobx";
|
import { runInAction } from "mobx";
|
||||||
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
|
||||||
|
|
||||||
export function registerInjectables(di: DiContainer) {
|
export function registerInjectables(di: DiContainer) {
|
||||||
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
|
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
|
||||||
|
|
||||||
|
registerMobX(di);
|
||||||
|
registerInjectableReact(di);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
registerMobX(di);
|
|
||||||
|
|
||||||
autoRegister({
|
autoRegister({
|
||||||
di,
|
di,
|
||||||
requireContexts: [
|
targetModule: module,
|
||||||
|
getRequireContexts: () => [
|
||||||
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
|
|||||||
@ -199,11 +199,11 @@
|
|||||||
"@k8slens/core": "^6.4.0-beta.13",
|
"@k8slens/core": "^6.4.0-beta.13",
|
||||||
"@k8slens/ensure-binaries": "^6.4.0-beta.13",
|
"@k8slens/ensure-binaries": "^6.4.0-beta.13",
|
||||||
"@k8slens/generate-tray-icons": "^6.4.0-beta.13",
|
"@k8slens/generate-tray-icons": "^6.4.0-beta.13",
|
||||||
"@ogre-tools/fp": "^12.0.1",
|
"@ogre-tools/fp": "^15.1.1",
|
||||||
"@ogre-tools/injectable": "^12.0.1",
|
"@ogre-tools/injectable": "^15.1.1",
|
||||||
"@ogre-tools/injectable-extension-for-auto-registration": "^12.0.1",
|
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
|
||||||
"@ogre-tools/injectable-extension-for-mobx": "^12.0.1",
|
"@ogre-tools/injectable-extension-for-mobx": "^15.1.1",
|
||||||
"@ogre-tools/injectable-react": "^12.0.1",
|
"@ogre-tools/injectable-react": "^15.1.1",
|
||||||
"mobx": "^6.8.0",
|
"mobx": "^6.8.0",
|
||||||
"rimraf": "^4.1.2"
|
"rimraf": "^4.1.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -13,7 +13,8 @@ runInAction(() => {
|
|||||||
try {
|
try {
|
||||||
autoRegister({
|
autoRegister({
|
||||||
di,
|
di,
|
||||||
requireContexts: [
|
targetModule: module,
|
||||||
|
getRequireContexts: () => [
|
||||||
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -13,7 +13,8 @@ const app = createApp({
|
|||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
autoRegister({
|
autoRegister({
|
||||||
di,
|
di,
|
||||||
requireContexts: [
|
targetModule: module,
|
||||||
|
getRequireContexts: () => [
|
||||||
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -16,15 +16,14 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@swc/cli": "^0.1.61",
|
"@swc/cli": "^0.1.61",
|
||||||
"@swc/core": "^1.3.35",
|
"@swc/core": "^1.3.35",
|
||||||
"@types/command-line-args": "^5.2.0",
|
"@types/inquirer": "^9.0.3",
|
||||||
"@types/fs-extra": "^11.0.1",
|
|
||||||
"@types/node": "^16.18.11",
|
"@types/node": "^16.18.11",
|
||||||
"@types/semver": "^7.3.13",
|
"@types/semver": "^7.3.13",
|
||||||
"command-line-args": "^5.2.1",
|
"rimraf": "^4.1.2"
|
||||||
"fs-extra": "^11.1.0",
|
|
||||||
"semver": "^7.3.8"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"rimraf": "^4.1.2"
|
"chalk": "^5.2.0",
|
||||||
|
"inquirer": "^9.1.4",
|
||||||
|
"semver": "^7.3.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,122 +3,34 @@
|
|||||||
* Copyright (c) OpenLens Authors. All rights reserved.
|
* Copyright (c) OpenLens Authors. All rights reserved.
|
||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
import child_process from "child_process";
|
import assert from "assert";
|
||||||
import commandLineArgs from "command-line-args";
|
import chalk from "chalk";
|
||||||
import fse from "fs-extra";
|
import child_process, { spawn } from "child_process";
|
||||||
import { basename } from "path";
|
import { readFile } from "fs/promises";
|
||||||
import { createInterface } from "readline";
|
import inquirer from "inquirer";
|
||||||
|
import { createInterface, ReadLine } from "readline";
|
||||||
import semver from "semver";
|
import semver from "semver";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
|
|
||||||
const {
|
type SemVer = semver.SemVer;
|
||||||
SemVer,
|
|
||||||
valid: semverValid,
|
const { SemVer } = semver;
|
||||||
rcompare: semverRcompare,
|
|
||||||
lte: semverLte,
|
|
||||||
} = semver;
|
|
||||||
const exec = promisify(child_process.exec);
|
const exec = promisify(child_process.exec);
|
||||||
const execFile = promisify(child_process.execFile);
|
const execFile = promisify(child_process.execFile);
|
||||||
|
|
||||||
const options = commandLineArgs([
|
async function pipeExecFile(file: string, args: string[], opts?: { stdin: string }) {
|
||||||
{
|
const p = execFile(file, args);
|
||||||
name: "type",
|
|
||||||
defaultOption: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "preid",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "check-commits",
|
|
||||||
type: Boolean,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const validReleaseValues = [
|
p.child.stdout?.pipe(process.stdout);
|
||||||
"major",
|
p.child.stderr?.pipe(process.stderr);
|
||||||
"minor",
|
|
||||||
"patch",
|
|
||||||
];
|
|
||||||
const validPrereleaseValues = [
|
|
||||||
"premajor",
|
|
||||||
"preminor",
|
|
||||||
"prepatch",
|
|
||||||
"prerelease",
|
|
||||||
];
|
|
||||||
const validPreidValues = [
|
|
||||||
"alpha",
|
|
||||||
"beta",
|
|
||||||
];
|
|
||||||
|
|
||||||
const errorMessages = {
|
if (opts) {
|
||||||
noReleaseType: `No release type provided. Valid options are: ${[...validReleaseValues, ...validPrereleaseValues].join(", ")}`,
|
p.child.stdin?.end(opts.stdin);
|
||||||
invalidRelease: (invalid: string) => `Invalid release type was provided (value was "${invalid}"). Valid options are: ${[...validReleaseValues, ...validPrereleaseValues].join(", ")}`,
|
|
||||||
noPreid: `No preid was provided. Use '--preid' to specify. Valid options are: ${validPreidValues.join(", ")}`,
|
|
||||||
invalidPreid: (invalid: string) => `Invalid preid was provided (value was "${invalid}"). Valid options are: ${validPreidValues.join(", ")}`,
|
|
||||||
wrongCwd: "It looks like you are running this script from the 'scripts' directory. This script assumes it is run from the root of the git repo",
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!options.type) {
|
|
||||||
console.error(errorMessages.noReleaseType);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validReleaseValues.includes(options.type)) {
|
|
||||||
// do nothing, is valid
|
|
||||||
} else if (validPrereleaseValues.includes(options.type)) {
|
|
||||||
if (!options.preid) {
|
|
||||||
console.error(errorMessages.noPreid);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!validPreidValues.includes(options.preid)) {
|
await p;
|
||||||
console.error(errorMessages.invalidPreid(options.preid));
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(errorMessages.invalidRelease(options.type));
|
|
||||||
process.exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (basename(process.cwd()) === "scripts") {
|
|
||||||
console.error(errorMessages.wrongCwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentVersion = new SemVer((await fse.readJson("./lerna.json")).version);
|
|
||||||
|
|
||||||
console.log(`current version: ${currentVersion.format()}`);
|
|
||||||
|
|
||||||
const newVersion = currentVersion.inc(options.type, options.preid);
|
|
||||||
const newVersionMilestone = `${newVersion.major}.${newVersion.minor}.${newVersion.patch}`;
|
|
||||||
const prBranch = `release/v${newVersion.format()}`;
|
|
||||||
|
|
||||||
await exec(`npm run bump-version --yes ${newVersion.format()}`);
|
|
||||||
await exec(`git checkout -b ${prBranch}`);
|
|
||||||
await exec("git add lerna.json packages/*/package.json");
|
|
||||||
await exec(`git commit -sm "Release ${newVersion.format()}"`);
|
|
||||||
|
|
||||||
console.log(`new version: ${newVersion.format()}`);
|
|
||||||
|
|
||||||
console.log("fetching tags...");
|
|
||||||
await exec("git fetch --tags --force");
|
|
||||||
|
|
||||||
const actualTags = (await exec("git tag --list", { encoding: "utf-8" })).stdout.split(/\r?\n/).map(line => line.trim());
|
|
||||||
const [previousReleasedVersion] = actualTags
|
|
||||||
.map((value) => semverValid(value))
|
|
||||||
.filter((v): v is string => typeof v === "string")
|
|
||||||
.sort((l, r) => semverRcompare(l, r))
|
|
||||||
.filter(version => semverLte(version, currentVersion));
|
|
||||||
|
|
||||||
const getMergedPrsArgs = [
|
|
||||||
"gh",
|
|
||||||
"pr",
|
|
||||||
"list",
|
|
||||||
"--limit=500", // Should be big enough, if not we need to release more often ;)
|
|
||||||
"--state=merged",
|
|
||||||
"--base=master",
|
|
||||||
"--json mergeCommit,title,author,labels,number,milestone,mergedAt",
|
|
||||||
];
|
|
||||||
|
|
||||||
interface GithubPrData {
|
interface GithubPrData {
|
||||||
author: {
|
author: {
|
||||||
login: string;
|
login: string;
|
||||||
@ -147,168 +59,285 @@ interface ExtendedGithubPrData extends Omit<GithubPrData, "mergedAt"> {
|
|||||||
mergedAt: Date;
|
mergedAt: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("retreiving last 500 PRs to create release PR body...");
|
async function getCurrentBranch(): Promise<string> {
|
||||||
const mergedPrs = JSON.parse((await exec(getMergedPrsArgs.join(" "), { encoding: "utf-8" })).stdout) as GithubPrData[];
|
return (await exec("git branch --show-current")).stdout.trim();
|
||||||
const milestoneRelevantPrs = mergedPrs.filter(pr => pr.milestone?.title === newVersionMilestone);
|
}
|
||||||
const relaventPrsQuery = await Promise.all(
|
|
||||||
milestoneRelevantPrs.map(async pr => ({
|
|
||||||
pr,
|
|
||||||
stdout: (await exec(`git tag v${previousReleasedVersion} --no-contains ${pr.mergeCommit.oid}`)).stdout,
|
|
||||||
})),
|
|
||||||
);
|
|
||||||
const relaventPrs = relaventPrsQuery
|
|
||||||
.filter(query => query.stdout)
|
|
||||||
.map(query => query.pr)
|
|
||||||
.filter(pr => pr.labels.every(label => label.name !== "skip-changelog"))
|
|
||||||
.map(pr => ({ ...pr, mergedAt: new Date(pr.mergedAt) } as ExtendedGithubPrData))
|
|
||||||
.sort((left, right) => {
|
|
||||||
const leftAge = left.mergedAt.valueOf();
|
|
||||||
const rightAge = right.mergedAt.valueOf();
|
|
||||||
|
|
||||||
if (leftAge === rightAge) {
|
async function getAbsolutePathToRepoRoot(): Promise<string> {
|
||||||
return 0;
|
return (await exec("git rev-parse --show-toplevel")).stdout.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (leftAge > rightAge) {
|
async function fetchAllGitTags(): Promise<string[]> {
|
||||||
return 1;
|
await execFile("git", ["fetch", "--tags", "--force"]);
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
const { stdout } = await exec("git tag --list", { encoding: "utf-8" });
|
||||||
|
|
||||||
|
return stdout
|
||||||
|
.split(/\r?\n/)
|
||||||
|
.map(line => line.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
function bumpPackageVersions() {
|
||||||
|
const bumpPackages = spawn("npm", ["run", "bump-version"], {
|
||||||
|
stdio: "inherit"
|
||||||
});
|
});
|
||||||
|
const cleaners: (() => void)[] = [
|
||||||
|
() => bumpPackages.stdout?.unpipe(),
|
||||||
|
() => bumpPackages.stderr?.unpipe(),
|
||||||
|
];
|
||||||
|
const cleanup = () => cleaners.forEach(clean => clean());
|
||||||
|
|
||||||
const enhancementPrLabelName = "enhancement";
|
return new Promise<void>((resolve, reject) => {
|
||||||
const bugfixPrLabelName = "bug";
|
const onExit = (code: number | null) => {
|
||||||
|
cleanup();
|
||||||
|
if (code) {
|
||||||
|
reject(new Error(`"npm run bump-version" failed with code ${code}`));
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const onError = (error: Error) => {
|
||||||
|
cleanup();
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
|
||||||
const isEnhancementPr = (pr: ExtendedGithubPrData) => pr.labels.some(label => label.name === enhancementPrLabelName);
|
bumpPackages.once("error", onError);
|
||||||
const isBugfixPr = (pr: ExtendedGithubPrData) => pr.labels.some(label => label.name === bugfixPrLabelName);
|
cleaners.push(() => bumpPackages.off("error", onError));
|
||||||
|
|
||||||
const prLines = {
|
bumpPackages.once("exit", onExit);
|
||||||
enhancement: [] as string[],
|
cleaners.push(() => bumpPackages.off("exit", onExit));
|
||||||
bugfix: [] as string[],
|
});
|
||||||
maintenence: [] as string[],
|
}
|
||||||
};
|
|
||||||
|
|
||||||
function getPrEntry(pr: ExtendedGithubPrData) {
|
function isDefined<T>(value: T | null | undefined): value is T {
|
||||||
|
return value != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findClosestVersionTagLessThanVersion(tags: string[], version: SemVer): string {
|
||||||
|
const lessThanTags = tags
|
||||||
|
.map((value) => semver.parse(value))
|
||||||
|
.filter(isDefined)
|
||||||
|
.filter(version => !version.prerelease.includes("cron"))
|
||||||
|
.sort(semver.rcompare)
|
||||||
|
.filter(version => semver.lte(version, version));
|
||||||
|
|
||||||
|
assert(lessThanTags.length > 0, `Cannot find version tag less than ${version.format()}`);
|
||||||
|
|
||||||
|
return lessThanTags[0].format();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getCurrentVersionOfSubPackage(packageName: string): Promise<SemVer> {
|
||||||
|
const packageJson = JSON.parse(await readFile(`./packages/${packageName}/package.json`, "utf-8"));
|
||||||
|
|
||||||
|
return new SemVer(packageJson.version);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkCurrentWorkingDirectory(): Promise<void> {
|
||||||
|
const repoRoot = await getAbsolutePathToRepoRoot();
|
||||||
|
|
||||||
|
if (process.cwd() !== repoRoot) {
|
||||||
|
console.error("It looks like you are running this script from the 'scripts' directory. This script assumes it is run from the root of the git repo");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatSemverForMilestone(version: SemVer): string {
|
||||||
|
return `${version.major}.${version.minor}.${version.patch}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createReleaseBranchAndCommit(prBase: string, version: SemVer, prBody: string): Promise<void> {
|
||||||
|
const prBranch = `release/v${version.format()}`;
|
||||||
|
|
||||||
|
await pipeExecFile("git", ["checkout", "-b", prBranch]);
|
||||||
|
await pipeExecFile("git", ["add", "lerna.json", "packages/*/package.json"]);
|
||||||
|
await pipeExecFile("git", ["commit", "-sm", `Release ${version.format()}`]);
|
||||||
|
await pipeExecFile("git", ["push", "--set-upstream", "origin", prBranch]);
|
||||||
|
|
||||||
|
await pipeExecFile("gh", [
|
||||||
|
"pr",
|
||||||
|
"create",
|
||||||
|
"--base", prBase,
|
||||||
|
"--title", `Release ${version.format()}`,
|
||||||
|
"--label", "skip-changelog",
|
||||||
|
"--label", "release",
|
||||||
|
"--milestone", formatSemverForMilestone(version),
|
||||||
|
"--body-file", "-",
|
||||||
|
], {
|
||||||
|
stdin: prBody,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortExtendedGithubPrData(left: ExtendedGithubPrData, right: ExtendedGithubPrData): number {
|
||||||
|
const leftAge = left.mergedAt.valueOf();
|
||||||
|
const rightAge = right.mergedAt.valueOf();
|
||||||
|
|
||||||
|
if (leftAge === rightAge) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftAge > rightAge) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getRelevantPRs(milestone: string, previousReleasedVersion: string): Promise<ExtendedGithubPrData[]> {
|
||||||
|
console.log("retrieving previous 200 PRs...");
|
||||||
|
|
||||||
|
const getMergedPrsArgs = [
|
||||||
|
"gh",
|
||||||
|
"pr",
|
||||||
|
"list",
|
||||||
|
"--limit=500", // Should be big enough, if not we need to release more often ;)
|
||||||
|
"--state=merged",
|
||||||
|
"--base=master",
|
||||||
|
"--json mergeCommit,title,author,labels,number,milestone,mergedAt",
|
||||||
|
];
|
||||||
|
|
||||||
|
const mergedPrs = JSON.parse((await exec(getMergedPrsArgs.join(" "), { encoding: "utf-8" })).stdout) as GithubPrData[];
|
||||||
|
const milestoneRelevantPrs = mergedPrs.filter(pr => pr.milestone?.title === milestone);
|
||||||
|
const relevantPrsQuery = await Promise.all(
|
||||||
|
milestoneRelevantPrs.map(async pr => ({
|
||||||
|
pr,
|
||||||
|
stdout: (await exec(`git tag v${previousReleasedVersion} --no-contains ${pr.mergeCommit.oid}`)).stdout,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
|
return relevantPrsQuery
|
||||||
|
.filter(query => query.stdout)
|
||||||
|
.map(query => query.pr)
|
||||||
|
.filter(pr => pr.labels.every(label => label.name !== "skip-changelog"))
|
||||||
|
.map(pr => ({ ...pr, mergedAt: new Date(pr.mergedAt) } as ExtendedGithubPrData))
|
||||||
|
.sort(sortExtendedGithubPrData);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatPrEntry(pr: ExtendedGithubPrData) {
|
||||||
return `- ${pr.title} (**[#${pr.number}](https://github.com/lensapp/lens/pull/${pr.number})**) https://github.com/${pr.author.login}`;
|
return `- ${pr.title} (**[#${pr.number}](https://github.com/lensapp/lens/pull/${pr.number})**) https://github.com/${pr.author.login}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rl = createInterface(process.stdin);
|
const isEnhancementPr = (pr: ExtendedGithubPrData) => pr.labels.some(label => label.name === "enhancement");
|
||||||
const prBase = newVersion.patch === 0
|
const isBugfixPr = (pr: ExtendedGithubPrData) => pr.labels.some(label => label.name === "bug");
|
||||||
? "master"
|
|
||||||
: `release/v${newVersion.major}.${newVersion.minor}`;
|
|
||||||
|
|
||||||
function askQuestion(question: string): Promise<boolean> {
|
const cherryPickCommitWith = (rl: ReadLine) => async (commit: string) => {
|
||||||
return new Promise<boolean>(resolve => {
|
try {
|
||||||
function _askQuestion() {
|
await pipeExecFile("git", ["cherry-pick", commit]);
|
||||||
console.log(question);
|
} catch {
|
||||||
|
console.error(chalk.bold("Please resolve conflicts in a separate terminal and then press enter here..."));
|
||||||
|
await new Promise<void>(resolve => rl.once("line", () => resolve()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
rl.once("line", (answer) => {
|
async function pickWhichPRsToUse(prs: ExtendedGithubPrData[]): Promise<ExtendedGithubPrData[]> {
|
||||||
const cleaned = answer.trim().toLowerCase();
|
const answers = await inquirer.prompt<{ commits: number[] }>({
|
||||||
|
type: "checkbox",
|
||||||
if (cleaned === "y") {
|
name: `commits`,
|
||||||
resolve(true);
|
message: "Pick which commits to use...",
|
||||||
} else if (cleaned === "n") {
|
default: [],
|
||||||
resolve(false);
|
choices: prs.map(pr => ({
|
||||||
} else {
|
checked: true,
|
||||||
_askQuestion();
|
key: pr.number,
|
||||||
}
|
name: `#${pr.number}: ${pr.title} (https://github.com/lensapp/lens/pull/${pr.number})`,
|
||||||
});
|
value: pr.number,
|
||||||
}
|
short: `#${pr.number}`,
|
||||||
|
})),
|
||||||
_askQuestion();
|
loop: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return prs.filter(pr => answers.commits.includes(pr.number));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleRelaventPr(pr: ExtendedGithubPrData) {
|
function formatChangelog(previousReleasedVersion: string, prs: ExtendedGithubPrData[]): string {
|
||||||
if (options["check-commits"] && !(await askQuestion(`Would you like to use #${pr.number}: ${pr.title}? - Y/N`))) {
|
const enhancementPrLines: string[] = [];
|
||||||
return;
|
const bugPrLines: string[] = [];
|
||||||
}
|
const maintenancePrLines: string[] = [];
|
||||||
|
|
||||||
if (prBase !== "master") {
|
for (const pr of prs) {
|
||||||
try {
|
if (isEnhancementPr(pr)) {
|
||||||
const promise = exec(`git cherry-pick ${pr.mergeCommit.oid}`);
|
enhancementPrLines.push(formatPrEntry(pr));
|
||||||
|
} else if (isBugfixPr(pr)) {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
bugPrLines.push(formatPrEntry(pr));
|
||||||
promise.child.stdout!.pipe(process.stdout);
|
} else {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
maintenancePrLines.push(formatPrEntry(pr));
|
||||||
promise.child.stderr!.pipe(process.stderr);
|
|
||||||
|
|
||||||
await promise;
|
|
||||||
} catch {
|
|
||||||
console.error(`Failed to cherry-pick ${pr.mergeCommit.oid}, please resolve conflicts and then press enter here:`);
|
|
||||||
await new Promise<void>(resolve => rl.once("line", () => resolve()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEnhancementPr(pr)) {
|
if (enhancementPrLines.length > 0) {
|
||||||
prLines.enhancement.push(getPrEntry(pr));
|
enhancementPrLines.unshift("## 🚀 Features", "");
|
||||||
} else if (isBugfixPr(pr)) {
|
enhancementPrLines.push("");
|
||||||
prLines.bugfix.push(getPrEntry(pr));
|
|
||||||
} else {
|
|
||||||
prLines.maintenence.push(getPrEntry(pr));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bugPrLines.length > 0) {
|
||||||
|
bugPrLines.unshift("## 🐛 Bug Fixes", "");
|
||||||
|
bugPrLines.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maintenancePrLines.length > 0) {
|
||||||
|
maintenancePrLines.unshift("## 🧰 Maintenance", "");
|
||||||
|
maintenancePrLines.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
`## Changes since ${previousReleasedVersion}`,
|
||||||
|
"",
|
||||||
|
...enhancementPrLines,
|
||||||
|
...bugPrLines,
|
||||||
|
...maintenancePrLines,
|
||||||
|
].join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const pr of relaventPrs) {
|
async function cherryPickCommits(prs: ExtendedGithubPrData[]): Promise<void> {
|
||||||
await handleRelaventPr(pr);
|
const rl = createInterface(process.stdin);
|
||||||
|
const cherryPickCommit = cherryPickCommitWith(rl);
|
||||||
|
|
||||||
|
for (const pr of prs) {
|
||||||
|
await cherryPickCommit(pr.mergeCommit.oid);
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.close();
|
async function pickRelevantPrs(prs: ExtendedGithubPrData[], isMasterBranch: boolean): Promise<ExtendedGithubPrData[]> {
|
||||||
|
if (isMasterBranch) {
|
||||||
|
return prs;
|
||||||
|
}
|
||||||
|
|
||||||
const prBodyLines = [
|
let selectedPrs: ExtendedGithubPrData[];
|
||||||
`## Changes since ${previousReleasedVersion}`,
|
|
||||||
"",
|
|
||||||
...(
|
|
||||||
prLines.enhancement.length > 0
|
|
||||||
? [
|
|
||||||
"## 🚀 Features",
|
|
||||||
"",
|
|
||||||
...prLines.enhancement,
|
|
||||||
"",
|
|
||||||
]
|
|
||||||
: []
|
|
||||||
),
|
|
||||||
...(
|
|
||||||
prLines.bugfix.length > 0
|
|
||||||
? [
|
|
||||||
"## 🐛 Bug Fixes",
|
|
||||||
"",
|
|
||||||
...prLines.bugfix,
|
|
||||||
"",
|
|
||||||
]
|
|
||||||
: []
|
|
||||||
),
|
|
||||||
...(
|
|
||||||
prLines.maintenence.length > 0
|
|
||||||
? [
|
|
||||||
"## 🧰 Maintenance",
|
|
||||||
"",
|
|
||||||
...prLines.maintenence,
|
|
||||||
"",
|
|
||||||
]
|
|
||||||
: []
|
|
||||||
),
|
|
||||||
];
|
|
||||||
const prBody = prBodyLines.join("\n");
|
|
||||||
const createPrArgs = [
|
|
||||||
"pr",
|
|
||||||
"create",
|
|
||||||
"--base", prBase,
|
|
||||||
"--title", `Release ${newVersion.format()}`,
|
|
||||||
"--label", "skip-changelog",
|
|
||||||
"--label", "release",
|
|
||||||
"--milestone", `${newVersion.major}.${newVersion.minor}.${newVersion.patch}`,
|
|
||||||
"--body-file", "-",
|
|
||||||
];
|
|
||||||
|
|
||||||
await exec(`git push --set-upstream origin ${prBranch}`);
|
do {
|
||||||
|
selectedPrs = await pickWhichPRsToUse(prs);
|
||||||
|
} while (selectedPrs.length === 0 && (console.warn("[WARNING]: must pick at least once commit"), true));
|
||||||
|
|
||||||
const createPrProcess = execFile("gh", createPrArgs);
|
await cherryPickCommits(selectedPrs);
|
||||||
|
|
||||||
createPrProcess.child.stdout?.pipe(process.stdout);
|
return selectedPrs;
|
||||||
createPrProcess.child.stderr?.pipe(process.stderr);
|
}
|
||||||
|
|
||||||
createPrProcess.child.stdin?.write(prBody);
|
async function createRelease(): Promise<void> {
|
||||||
createPrProcess.child.stdin?.end();
|
await checkCurrentWorkingDirectory();
|
||||||
|
|
||||||
await createPrProcess;
|
const currentK8slensCoreVersion = await getCurrentVersionOfSubPackage("core");
|
||||||
|
const prBase = await getCurrentBranch();
|
||||||
|
const isMasterBranch = prBase === "master";
|
||||||
|
const tags = await fetchAllGitTags();
|
||||||
|
const previousReleasedVersion = findClosestVersionTagLessThanVersion(tags, currentK8slensCoreVersion);
|
||||||
|
|
||||||
|
if (isMasterBranch) {
|
||||||
|
await bumpPackageVersions();
|
||||||
|
}
|
||||||
|
|
||||||
|
const prMilestone = formatSemverForMilestone(await getCurrentVersionOfSubPackage("core"));
|
||||||
|
const relevantPrs = await getRelevantPRs(prMilestone, previousReleasedVersion);
|
||||||
|
const selectedPrs = await pickRelevantPrs(relevantPrs, isMasterBranch);
|
||||||
|
const prBody = formatChangelog(previousReleasedVersion, selectedPrs);
|
||||||
|
|
||||||
|
if (!isMasterBranch) {
|
||||||
|
await bumpPackageVersions();
|
||||||
|
}
|
||||||
|
|
||||||
|
const newK8slensCoreVersion = await getCurrentVersionOfSubPackage("core");
|
||||||
|
|
||||||
|
await createReleaseBranchAndCommit(prBase, newK8slensCoreVersion, prBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
await createRelease();
|
||||||
|
|||||||
@ -29,8 +29,8 @@
|
|||||||
"test": "jest --coverage --runInBand"
|
"test": "jest --coverage --runInBand"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ogre-tools/fp": "^12.0.1",
|
"@ogre-tools/fp": "^15.1.1",
|
||||||
"@ogre-tools/injectable": "^12.0.1",
|
"@ogre-tools/injectable": "^15.1.1",
|
||||||
"lodash": "^4.17.15"
|
"lodash": "^4.17.15"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
41
packages/technical-features/feature-core/README.md
Normal file
41
packages/technical-features/feature-core/README.md
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# @k8slens/feature-core
|
||||||
|
|
||||||
|
Feature is set of injectables that are registered and deregistered simultaneously.
|
||||||
|
|
||||||
|
## Install
|
||||||
|
```bash
|
||||||
|
$ npm install @k8slens/feature-core
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { createContainer } from "@ogre-tools/injectable"
|
||||||
|
import { getFeature, registerFeature, deregisterFeature } from "@k8slens/feature-core"
|
||||||
|
|
||||||
|
// Notice that this Feature is usually exported from another NPM package.
|
||||||
|
const someFeature = getFeature({
|
||||||
|
id: "some-feature",
|
||||||
|
|
||||||
|
register: (di) => {
|
||||||
|
di.register(someInjectable, someOtherInjectable);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Feature dependencies are automatically registered and
|
||||||
|
// deregistered when necessary.
|
||||||
|
dependencies: [someOtherFeature]
|
||||||
|
});
|
||||||
|
|
||||||
|
const di = createContainer("some-container");
|
||||||
|
|
||||||
|
registerFeature(di, someFeature);
|
||||||
|
|
||||||
|
// Or perhaps you want to deregister?
|
||||||
|
deregisterFeature(di, someFeature);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Need to know
|
||||||
|
|
||||||
|
#### NPM packages exporting a Feature
|
||||||
|
- Prefer `peerDependencies` since they are installed from the application and are not allowed to be in the built bundle.
|
||||||
|
- Prefer exporting `injectionToken` instead of `injectable` for not allowing other features to access technical details like the `injectable`
|
||||||
3
packages/technical-features/feature-core/index.ts
Normal file
3
packages/technical-features/feature-core/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export { getFeature } from "./src/feature";
|
||||||
|
export { registerFeature } from "./src/register-feature";
|
||||||
|
export type { Feature, GetFeatureArgs } from "./src/feature";
|
||||||
2
packages/technical-features/feature-core/jest.config.js
Normal file
2
packages/technical-features/feature-core/jest.config.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module.exports =
|
||||||
|
require("@k8slens/jest").monorepoPackageConfig(__dirname).configForReact;
|
||||||
30
packages/technical-features/feature-core/package.json
Normal file
30
packages/technical-features/feature-core/package.json
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "@k8slens/feature-core",
|
||||||
|
"private": false,
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "Code that is common to all Features and those registering them.",
|
||||||
|
"type": "commonjs",
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/lensapp/lens.git"
|
||||||
|
},
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"author": {
|
||||||
|
"name": "OpenLens Authors",
|
||||||
|
"email": "info@k8slens.dev"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"homepage": "https://github.com/lensapp/lens",
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack",
|
||||||
|
"dev": "webpack --mode=development --watch",
|
||||||
|
"test": "jest --coverage --runInBand"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@ogre-tools/injectable": "^15.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
|
import type { Feature } from "./feature";
|
||||||
|
import { featureContextMapInjectable } from "./feature-context-map-injectable";
|
||||||
|
|
||||||
|
export const deregisterFeature = (di: DiContainer, ...features: Feature[]) => {
|
||||||
|
features.forEach((feature) => {
|
||||||
|
deregisterFeatureRecursed(di, feature);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const deregisterFeatureRecursed = (
|
||||||
|
di: DiContainer,
|
||||||
|
feature: Feature,
|
||||||
|
dependedBy?: Feature
|
||||||
|
) => {
|
||||||
|
const featureContextMap = di.inject(featureContextMapInjectable);
|
||||||
|
|
||||||
|
const featureContext = featureContextMap.get(feature);
|
||||||
|
|
||||||
|
if (!featureContext) {
|
||||||
|
throw new Error(
|
||||||
|
`Tried to deregister feature "${feature.id}", but it was not registered.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
featureContext.numberOfRegistrations--;
|
||||||
|
|
||||||
|
const getDependingFeatures = getDependingFeaturesFor(featureContextMap);
|
||||||
|
|
||||||
|
const dependingFeatures = getDependingFeatures(feature);
|
||||||
|
|
||||||
|
if (!dependedBy && dependingFeatures.length) {
|
||||||
|
throw new Error(
|
||||||
|
`Tried to deregister Feature "${
|
||||||
|
feature.id
|
||||||
|
}", but it is the dependency of Features "${dependingFeatures.join(
|
||||||
|
", "
|
||||||
|
)}"`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependedBy) {
|
||||||
|
const oldNumberOfDependents = featureContext.dependedBy.get(dependedBy)!;
|
||||||
|
const newNumberOfDependants = oldNumberOfDependents - 1;
|
||||||
|
featureContext.dependedBy.set(dependedBy, newNumberOfDependants);
|
||||||
|
|
||||||
|
if (newNumberOfDependants === 0) {
|
||||||
|
featureContext.dependedBy.delete(dependedBy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (featureContext.numberOfRegistrations === 0) {
|
||||||
|
featureContextMap.delete(feature);
|
||||||
|
|
||||||
|
featureContext.deregister();
|
||||||
|
}
|
||||||
|
|
||||||
|
feature.dependencies?.forEach((dependency) => {
|
||||||
|
deregisterFeatureRecursed(di, dependency, feature);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const getDependingFeaturesFor = (
|
||||||
|
featureContextMap: Map<Feature, { dependedBy: Map<Feature, number> }>
|
||||||
|
) => {
|
||||||
|
const getDependingFeaturesForRecursion = (
|
||||||
|
feature: Feature,
|
||||||
|
atRoot = true
|
||||||
|
): string[] => {
|
||||||
|
const context = featureContextMap.get(feature);
|
||||||
|
|
||||||
|
if (context?.dependedBy.size) {
|
||||||
|
return [...context!.dependedBy.entries()].flatMap(([dependant]) =>
|
||||||
|
getDependingFeaturesForRecursion(dependant, false)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return atRoot ? [] : [feature.id];
|
||||||
|
};
|
||||||
|
|
||||||
|
return getDependingFeaturesForRecursion;
|
||||||
|
};
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
import { getInjectable, getInjectionToken } from "@ogre-tools/injectable";
|
||||||
|
import type { Feature } from "./feature";
|
||||||
|
|
||||||
|
export type FeatureContextMap = Map<
|
||||||
|
Feature,
|
||||||
|
{
|
||||||
|
register: () => void;
|
||||||
|
deregister: () => void;
|
||||||
|
dependedBy: Map<Feature, number>;
|
||||||
|
numberOfRegistrations: number;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
|
||||||
|
export const featureContextMapInjectionToken =
|
||||||
|
getInjectionToken<FeatureContextMap>({
|
||||||
|
id: "feature-context-map-injection-token",
|
||||||
|
});
|
||||||
|
|
||||||
|
const featureContextMapInjectable = getInjectable({
|
||||||
|
id: "feature-store",
|
||||||
|
|
||||||
|
instantiate: (): FeatureContextMap => new Map(),
|
||||||
|
|
||||||
|
injectionToken: featureContextMapInjectionToken,
|
||||||
|
});
|
||||||
|
|
||||||
|
export { featureContextMapInjectable };
|
||||||
@ -0,0 +1,281 @@
|
|||||||
|
import {
|
||||||
|
createContainer,
|
||||||
|
DiContainer,
|
||||||
|
getInjectable,
|
||||||
|
Injectable,
|
||||||
|
} from "@ogre-tools/injectable";
|
||||||
|
|
||||||
|
import type { Feature } from "./feature";
|
||||||
|
import { registerFeature } from "./register-feature";
|
||||||
|
import { deregisterFeature } from "./deregister-feature";
|
||||||
|
import { getFeature } from "./feature" ;
|
||||||
|
|
||||||
|
describe("feature-dependencies", () => {
|
||||||
|
describe("given a parent Feature with another Features as dependency", () => {
|
||||||
|
let di: DiContainer;
|
||||||
|
let someInjectable: Injectable<string>;
|
||||||
|
let someInjectableInDependencyFeature: Injectable<string>;
|
||||||
|
let someParentFeature: Feature;
|
||||||
|
let someDependencyFeature: Feature;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
di = createContainer("irrelevant");
|
||||||
|
|
||||||
|
someInjectable = getInjectable({
|
||||||
|
id: "some-injectable-2",
|
||||||
|
instantiate: () => "some-instance",
|
||||||
|
});
|
||||||
|
|
||||||
|
someInjectableInDependencyFeature = getInjectable({
|
||||||
|
id: "some-injectable",
|
||||||
|
instantiate: () => "some-instance-2",
|
||||||
|
});
|
||||||
|
|
||||||
|
someDependencyFeature = getFeature({
|
||||||
|
id: "some-dependency-feature",
|
||||||
|
register: (di) => di.register(someInjectableInDependencyFeature),
|
||||||
|
});
|
||||||
|
|
||||||
|
someParentFeature = getFeature({
|
||||||
|
id: "some-feature",
|
||||||
|
register: (di) => di.register(someInjectable),
|
||||||
|
dependencies: [someDependencyFeature],
|
||||||
|
});
|
||||||
|
|
||||||
|
registerFeature(di, someParentFeature);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when an injectable from the dependency Feature is injected, does so", () => {
|
||||||
|
const actual = di.inject(someInjectableInDependencyFeature);
|
||||||
|
|
||||||
|
expect(actual).toBe("some-instance-2");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when the dependency Feature is deregistered, throws", () => {
|
||||||
|
expect(() => {
|
||||||
|
deregisterFeature(di, someDependencyFeature);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to deregister Feature "some-dependency-feature", but it is the dependency of Features "some-feature"'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given the parent Feature is already deregistered, when also the dependency Feature is deregistered, throws", () => {
|
||||||
|
deregisterFeature(di, someParentFeature);
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
deregisterFeature(di, someDependencyFeature);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to deregister feature "some-dependency-feature", but it was not registered.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given the parent Feature is deregistered, when injecting an injectable from the dependency Feature, throws", () => {
|
||||||
|
deregisterFeature(di, someParentFeature);
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
di.inject(someInjectableInDependencyFeature);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to inject non-registered injectable "irrelevant" -> "some-injectable".'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given a first Feature is registered, when second Feature using the first Feature as dependency gets registered", () => {
|
||||||
|
let di: DiContainer;
|
||||||
|
let someInjectable: Injectable<string>;
|
||||||
|
let someFeature2: Feature;
|
||||||
|
let someFeature1: Feature;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
di = createContainer("irrelevant");
|
||||||
|
|
||||||
|
someInjectable = getInjectable({
|
||||||
|
id: "some-injectable",
|
||||||
|
instantiate: () => "some-instance",
|
||||||
|
});
|
||||||
|
|
||||||
|
someFeature1 = getFeature({
|
||||||
|
id: "some-feature-1",
|
||||||
|
register: (di) => di.register(someInjectable),
|
||||||
|
});
|
||||||
|
|
||||||
|
someFeature2 = getFeature({
|
||||||
|
id: "some-feature-2",
|
||||||
|
register: () => {},
|
||||||
|
dependencies: [someFeature1],
|
||||||
|
});
|
||||||
|
|
||||||
|
registerFeature(di, someFeature1, someFeature2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when the first Feature is deregistered, throws", () => {
|
||||||
|
expect(() => {
|
||||||
|
deregisterFeature(di, someFeature1);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to deregister Feature "some-feature-1", but it is the dependency of Features "some-feature-2"'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given the second Feature is deregistered, when injecting an injectable from the first Feature, still does so", () => {
|
||||||
|
deregisterFeature(di, someFeature2);
|
||||||
|
|
||||||
|
const actual = di.inject(someInjectable);
|
||||||
|
|
||||||
|
expect(actual).toBe("some-instance");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given parent Features with a shared Feature as dependency", () => {
|
||||||
|
let di: DiContainer;
|
||||||
|
let someInjectableInDependencyFeature: Injectable<string>;
|
||||||
|
let someFeature1: Feature;
|
||||||
|
let someFeature2: Feature;
|
||||||
|
let someSharedDependencyFeature: Feature;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
di = createContainer("irrelevant");
|
||||||
|
|
||||||
|
someInjectableInDependencyFeature = getInjectable({
|
||||||
|
id: "some-injectable-in-dependency-feature",
|
||||||
|
instantiate: () => "some-instance",
|
||||||
|
});
|
||||||
|
|
||||||
|
someSharedDependencyFeature = getFeature({
|
||||||
|
id: "some-dependency-feature",
|
||||||
|
register: (di) => di.register(someInjectableInDependencyFeature),
|
||||||
|
});
|
||||||
|
|
||||||
|
const someFeatureForAdditionalHierarchy = getFeature({
|
||||||
|
id: "some-feature-for-additional-hierarchy",
|
||||||
|
register: () => {},
|
||||||
|
dependencies: [someSharedDependencyFeature],
|
||||||
|
});
|
||||||
|
|
||||||
|
someFeature1 = getFeature({
|
||||||
|
id: "some-feature-1",
|
||||||
|
register: () => {},
|
||||||
|
dependencies: [someFeatureForAdditionalHierarchy],
|
||||||
|
});
|
||||||
|
|
||||||
|
someFeature2 = getFeature({
|
||||||
|
id: "some-feature-2",
|
||||||
|
register: () => {},
|
||||||
|
dependencies: [someFeatureForAdditionalHierarchy],
|
||||||
|
});
|
||||||
|
|
||||||
|
registerFeature(di, someFeature1, someFeature2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when the shared Feature is deregistered, throws", () => {
|
||||||
|
expect(() => {
|
||||||
|
deregisterFeature(di, someSharedDependencyFeature);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to deregister Feature "some-dependency-feature", but it is the dependency of Features "some-feature-1, some-feature-2"'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given only part of the parent Features get deregistered, when injecting an injectable from the shared Feature, does so", () => {
|
||||||
|
deregisterFeature(di, someFeature1);
|
||||||
|
|
||||||
|
const actual = di.inject(someInjectableInDependencyFeature);
|
||||||
|
|
||||||
|
expect(actual).toBe("some-instance");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given all of the parent Features get deregistered, when injecting an injectable from the shared Feature, throws", () => {
|
||||||
|
deregisterFeature(di, someFeature1, someFeature2);
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
di.inject(someInjectableInDependencyFeature);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to inject non-registered injectable "irrelevant" -> "some-injectable-in-dependency-feature".'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given parent Features with a shared Feature as dependency and registered, when the shared Feature gets registered again", () => {
|
||||||
|
let di: DiContainer;
|
||||||
|
let someInjectableInDependencyFeature: Injectable<string>;
|
||||||
|
let someFeature1: Feature;
|
||||||
|
let someFeature2: Feature;
|
||||||
|
let someSharedDependencyFeature: Feature;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
di = createContainer("irrelevant");
|
||||||
|
|
||||||
|
someInjectableInDependencyFeature = getInjectable({
|
||||||
|
id: "some-injectable-in-dependency-feature",
|
||||||
|
instantiate: () => "some-instance",
|
||||||
|
});
|
||||||
|
|
||||||
|
someSharedDependencyFeature = getFeature({
|
||||||
|
id: "some-dependency-feature",
|
||||||
|
register: (di) => di.register(someInjectableInDependencyFeature),
|
||||||
|
});
|
||||||
|
|
||||||
|
const someFeatureForAdditionalHierarchy = getFeature({
|
||||||
|
id: "some-feature-for-additional-hierarchy",
|
||||||
|
register: () => {},
|
||||||
|
dependencies: [someSharedDependencyFeature],
|
||||||
|
});
|
||||||
|
|
||||||
|
someFeature1 = getFeature({
|
||||||
|
id: "some-feature-1",
|
||||||
|
register: () => {},
|
||||||
|
dependencies: [someFeatureForAdditionalHierarchy],
|
||||||
|
});
|
||||||
|
|
||||||
|
someFeature2 = getFeature({
|
||||||
|
id: "some-feature-2",
|
||||||
|
register: () => {},
|
||||||
|
dependencies: [someFeatureForAdditionalHierarchy],
|
||||||
|
});
|
||||||
|
|
||||||
|
registerFeature(
|
||||||
|
di,
|
||||||
|
someFeature1,
|
||||||
|
someFeature2,
|
||||||
|
someSharedDependencyFeature
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when the shared Feature is deregistered, throws", () => {
|
||||||
|
expect(() => {
|
||||||
|
deregisterFeature(di, someSharedDependencyFeature);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to deregister Feature "some-dependency-feature", but it is the dependency of Features "some-feature-1, some-feature-2"'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given only part of the parent Features get deregistered, when injecting an injectable from the shared Feature, does so", () => {
|
||||||
|
deregisterFeature(di, someFeature1);
|
||||||
|
|
||||||
|
const actual = di.inject(someInjectableInDependencyFeature);
|
||||||
|
|
||||||
|
expect(actual).toBe("some-instance");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given all of the parent Features get deregistered, when injecting an injectable from the shared Feature, still does so", () => {
|
||||||
|
deregisterFeature(di, someFeature1, someFeature2);
|
||||||
|
|
||||||
|
const actual = di.inject(someInjectableInDependencyFeature);
|
||||||
|
|
||||||
|
expect(actual).toBe("some-instance");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given all of the Features get deregistered, when injecting an injectable from the shared Feature, throws", () => {
|
||||||
|
deregisterFeature(
|
||||||
|
di,
|
||||||
|
someFeature1,
|
||||||
|
someFeature2,
|
||||||
|
someSharedDependencyFeature
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
di.inject(someInjectableInDependencyFeature);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to inject non-registered injectable "irrelevant" -> "some-injectable-in-dependency-feature".'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
12
packages/technical-features/feature-core/src/feature.ts
Normal file
12
packages/technical-features/feature-core/src/feature.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import type { DiContainerForInjection } from "@ogre-tools/injectable";
|
||||||
|
|
||||||
|
export interface Feature {
|
||||||
|
id: string;
|
||||||
|
register: (di: DiContainerForInjection) => void;
|
||||||
|
dependencies?: Feature[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GetFeatureArgs extends Feature {}
|
||||||
|
|
||||||
|
export const getFeature = (getFeatureArgs: GetFeatureArgs): Feature =>
|
||||||
|
getFeatureArgs;
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
import type { DiContainer } from "@ogre-tools/injectable";
|
||||||
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
|
import type { Feature } from "./feature";
|
||||||
|
import {
|
||||||
|
featureContextMapInjectable,
|
||||||
|
featureContextMapInjectionToken,
|
||||||
|
} from "./feature-context-map-injectable";
|
||||||
|
|
||||||
|
export const registerFeature = (di: DiContainer, ...features: Feature[]) => {
|
||||||
|
features.forEach((feature) => {
|
||||||
|
registerFeatureRecursed(di, feature);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const registerFeatureRecursed = (
|
||||||
|
di: DiContainer,
|
||||||
|
feature: Feature,
|
||||||
|
dependedBy?: Feature
|
||||||
|
) => {
|
||||||
|
const featureContextMaps = di.injectMany(featureContextMapInjectionToken);
|
||||||
|
|
||||||
|
if (featureContextMaps.length === 0) {
|
||||||
|
di.register(featureContextMapInjectable);
|
||||||
|
}
|
||||||
|
|
||||||
|
const featureContextMap = di.inject(featureContextMapInjectable);
|
||||||
|
|
||||||
|
const existingFeatureContext = featureContextMap.get(feature);
|
||||||
|
if (
|
||||||
|
!dependedBy &&
|
||||||
|
existingFeatureContext &&
|
||||||
|
existingFeatureContext.dependedBy.size === 0
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`Tried to register feature "${feature.id}", but it was already registered.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const featureContext =
|
||||||
|
existingFeatureContext || createFeatureContext(feature, di);
|
||||||
|
|
||||||
|
featureContext.numberOfRegistrations++;
|
||||||
|
|
||||||
|
if (dependedBy) {
|
||||||
|
const oldNumberOfDependents =
|
||||||
|
featureContext.dependedBy.get(dependedBy) || 0;
|
||||||
|
|
||||||
|
const newNumberOfDependants = oldNumberOfDependents + 1;
|
||||||
|
featureContext.dependedBy.set(dependedBy, newNumberOfDependants);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existingFeatureContext) {
|
||||||
|
featureContext.register();
|
||||||
|
}
|
||||||
|
|
||||||
|
feature.dependencies?.forEach((dependency) => {
|
||||||
|
registerFeatureRecursed(di, dependency, feature);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const createFeatureContext = (feature: Feature, di: DiContainer) => {
|
||||||
|
const featureContextInjectable = getInjectable({
|
||||||
|
id: feature.id,
|
||||||
|
|
||||||
|
instantiate: (diForContextOfFeature) => ({
|
||||||
|
register: () => {
|
||||||
|
feature.register(diForContextOfFeature);
|
||||||
|
},
|
||||||
|
|
||||||
|
deregister: () => {
|
||||||
|
diForContextOfFeature.deregister(featureContextInjectable);
|
||||||
|
},
|
||||||
|
|
||||||
|
dependedBy: new Map<Feature, number>(),
|
||||||
|
|
||||||
|
numberOfRegistrations: 0,
|
||||||
|
}),
|
||||||
|
|
||||||
|
scope: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
di.register(featureContextInjectable);
|
||||||
|
|
||||||
|
const featureContextMap = di.inject(featureContextMapInjectable);
|
||||||
|
const featureContext = di.inject(featureContextInjectable);
|
||||||
|
|
||||||
|
featureContextMap.set(feature, featureContext);
|
||||||
|
|
||||||
|
return featureContext;
|
||||||
|
};
|
||||||
@ -0,0 +1,147 @@
|
|||||||
|
import { registerFeature } from "./register-feature";
|
||||||
|
import {
|
||||||
|
createContainer,
|
||||||
|
DiContainer,
|
||||||
|
getInjectable,
|
||||||
|
Injectable,
|
||||||
|
} from "@ogre-tools/injectable";
|
||||||
|
import type { Feature } from "./feature";
|
||||||
|
import { getFeature } from "./feature";
|
||||||
|
import { deregisterFeature } from "./deregister-feature";
|
||||||
|
|
||||||
|
describe("register-feature", () => {
|
||||||
|
describe("given di-container and a Features with injectables, and given Features are registered", () => {
|
||||||
|
let di: DiContainer;
|
||||||
|
let someInjectable: Injectable<string>;
|
||||||
|
let someInjectable2: Injectable<string>;
|
||||||
|
let someFeature: Feature;
|
||||||
|
let someFeature2: Feature;
|
||||||
|
let instance: string;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
di = createContainer("irrelevant");
|
||||||
|
|
||||||
|
someInjectable = getInjectable({
|
||||||
|
id: "some-injectable",
|
||||||
|
instantiate: () => "some-instance",
|
||||||
|
});
|
||||||
|
|
||||||
|
someInjectable2 = getInjectable({
|
||||||
|
id: "some-injectable-2",
|
||||||
|
instantiate: () => "some-instance-2",
|
||||||
|
});
|
||||||
|
|
||||||
|
someFeature = getFeature({
|
||||||
|
id: "some-feature-1",
|
||||||
|
register: (di) => di.register(someInjectable),
|
||||||
|
});
|
||||||
|
|
||||||
|
someFeature2 = getFeature({
|
||||||
|
id: "some-feature-2",
|
||||||
|
register: (di) => di.register(someInjectable2),
|
||||||
|
});
|
||||||
|
|
||||||
|
registerFeature(di, someFeature);
|
||||||
|
registerFeature(di, someFeature2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when an injectable is injected, does so", () => {
|
||||||
|
instance = di.inject(someInjectable);
|
||||||
|
|
||||||
|
expect(instance).toBe("some-instance");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given a Feature is deregistered", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
deregisterFeature(di, someFeature);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when injecting a related injectable, throws", () => {
|
||||||
|
expect(() => {
|
||||||
|
di.inject(someInjectable);
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when injecting an unrelated injectable, does so", () => {
|
||||||
|
const instance = di.inject(someInjectable2);
|
||||||
|
|
||||||
|
expect(instance).toBe("some-instance-2");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("given the Feature is registered again", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
registerFeature(di, someFeature);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when injecting a related injectable, does so", () => {
|
||||||
|
const instance = di.inject(someInjectable);
|
||||||
|
|
||||||
|
expect(instance).toBe("some-instance");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when injecting an unrelated injectable, does so", () => {
|
||||||
|
const instance = di.inject(someInjectable2);
|
||||||
|
|
||||||
|
expect(instance).toBe("some-instance-2");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("when a Feature is registered again, throws", () => {
|
||||||
|
expect(() => {
|
||||||
|
registerFeature(di, someFeature);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to register feature "some-feature-1", but it was already registered.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given a Feature deregistered, when deregistered again, throws", () => {
|
||||||
|
deregisterFeature(di, someFeature);
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
deregisterFeature(di, someFeature);
|
||||||
|
}).toThrow(
|
||||||
|
'Tried to deregister feature "some-feature-1", but it was not registered.'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("given di-container and registered Features with injectables forming a cycle, when an injectable is injected, throws with namespaced error about cycle", () => {
|
||||||
|
const someInjectable: Injectable<any> = getInjectable({
|
||||||
|
id: "some-injectable-1",
|
||||||
|
instantiate: (di) => di.inject(someInjectable2),
|
||||||
|
});
|
||||||
|
|
||||||
|
const someInjectable2: Injectable<any> = getInjectable({
|
||||||
|
id: "some-injectable-2",
|
||||||
|
instantiate: (di) => di.inject(someInjectable),
|
||||||
|
});
|
||||||
|
|
||||||
|
const di = createContainer("some-container");
|
||||||
|
|
||||||
|
const someFeature = getFeature({
|
||||||
|
id: "some-feature-1",
|
||||||
|
|
||||||
|
register: (di) => {
|
||||||
|
di.register(someInjectable);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const someFeature2 = getFeature({
|
||||||
|
id: "some-feature-2",
|
||||||
|
|
||||||
|
register: (di) => {
|
||||||
|
di.register(someInjectable2);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
registerFeature(di, someFeature, someFeature2);
|
||||||
|
|
||||||
|
expect(() => {
|
||||||
|
di.inject(someInjectable);
|
||||||
|
}).toThrow(
|
||||||
|
// 'Cycle of injectables encountered: "some-container" -> "some-feature-1:some-injectable-1" -> "some-feature-2:some-injectable-2" -> "some-feature-1:some-injectable-1"'
|
||||||
|
'Maximum call stack size exceeded'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
3
packages/technical-features/feature-core/tsconfig.json
Normal file
3
packages/technical-features/feature-core/tsconfig.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "@k8slens/typescript/config/base.json"
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
module.exports = require("@k8slens/webpack").configForNode;
|
||||||
Loading…
Reference in New Issue
Block a user