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

Allow to import app as a library (#6722)

* unify build fs layout

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* use currentApp path for static files

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* lint fix

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* allow to import open-lens

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* allow to customize both main & renderer

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix compile-library script

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* remove bundled extensions

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* similar interface for both main & renderer

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* use startApp on both sides

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix startApp import

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix startApp import

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* Fix injection cycle (somehow)

Signed-off-by: Sebastian Malton <sebastian@malton.name>

* use cwd in download_binaries

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* introduce applicationInformationToken

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* register applicationInformationInjectable in main & renderer

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* allow to define bundled extensions via appStart

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* compile node-fetch automatically via prepare

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* define peerDependencies

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* webpack fixes

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* rename application-information-token.injectable.ts -> application-information-token.ts

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* monaco-editor as externals

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* refactor application-information

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* introduce bundledExtensionInjectionToken

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* mark library exports as experimental

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* move extension npm package files & add release automation

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* add missing build files to package

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix bad merge conflict resolve

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix package.json name

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* allow to set mode via startApp

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* revert unnecessary changes

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* webpack: fix extensionOutDir

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* remove unnecessary peerDependencies

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* introduce nodeEnvInjectionToken

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* remove NODE_ENV from environmentVariablesInjectable

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix jest modulePathIgnorePatterns

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix duplicate injectable registration

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

* fix build executableName

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>

Signed-off-by: Jari Kolehmainen <jari.kolehmainen@gmail.com>
Signed-off-by: Sebastian Malton <sebastian@malton.name>
Co-authored-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Jari Kolehmainen 2022-12-23 13:33:35 +02:00 committed by GitHub
parent ba908c860d
commit 97551bb7f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 712 additions and 263 deletions

View File

@ -1,17 +1,16 @@
name: Publish NPM Package `master`
on:
push:
branches:
- master
pull_request:
types:
- closed
concurrency:
group: publish-master-npm
cancel-in-progress: true
jobs:
publish:
name: Publish NPM Package `master`
name: Publish Extensions NPM Package `master`
runs-on: ubuntu-latest
if: |
${{ github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'area/extension') }}
if: ${{ github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'area/extension') }}
strategy:
matrix:
node-version: [16.x]
@ -28,11 +27,11 @@ jobs:
- name: Generate NPM package
run: |
make build-npm
make build-extensions-npm
- name: publish new release
run: |
make publish-npm
make publish-extensions-npm
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_RELEASE_TAG: master

View File

@ -12,8 +12,8 @@ on:
type: string
description: The version to release manually
jobs:
publish:
name: Publish NPM Package Release
publish-extensions:
name: Publish Extensions NPM Package Release
runs-on: ubuntu-latest
strategy:
matrix:
@ -32,10 +32,37 @@ jobs:
- name: Generate NPM package
run: |
make build-npm
make build-extensions-npm
- name: publish new release
- name: Publish NPM package
run: |
make publish-npm
make publish-extensions-npm
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
publish-library:
name: Publish Library NPM Package Release
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16.x]
steps:
- name: Checkout Release
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ inputs.version }}
- name: Using Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Generate NPM package
run: |
make build-library-npm
- name: Publish NPM package
run: |
make publish-library-npm
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

4
.gitignore vendored
View File

@ -10,10 +10,6 @@ static/build
static/types
binaries/client/
binaries/server/
src/extensions/*/*.js
src/extensions/*/*.d.ts
types/extension-api.d.ts
types/extension-renderer-api.d.ts
docs/extensions/api
site/
build/webpack/

View File

@ -61,24 +61,32 @@ endif
src/extensions/npm/extensions/__mocks__:
cp -r __mocks__ src/extensions/npm/extensions/
src/extensions/npm/extensions/dist: src/extensions/npm/extensions/node_modules
packages/extensions/dist: packages/extensions/node_modules
yarn compile:extension-types
src/extensions/npm/extensions/node_modules: src/extensions/npm/extensions/package.json
cd src/extensions/npm/extensions/ && ../../../../node_modules/.bin/npm install --no-audit --no-fund --no-save
packages/extensions/node_modules: packages/extensions/package.json
cd packages/extensions/ && ../../node_modules/.bin/npm install --no-audit --no-fund --no-save
.PHONY: build-npm
build-npm: build-extension-types src/extensions/npm/extensions/__mocks__
yarn npm:fix-package-version
.PHONY: build-extensions-npm
build-extensions-npm: build-extension-types packages/extensions/__mocks__
yarn npm:fix-extensions-package-version
.PHONY: build-library-npm
build-library-npm:
yarn compile-library
.PHONY: build-extension-types
build-extension-types: node_modules src/extensions/npm/extensions/dist
build-extension-types: node_modules packages/extensions/dist
.PHONY: publish-npm
publish-npm: node_modules build-npm
.PHONY: publish-extensions-npm
publish-extensions-npm: node_modules build-extensions-npm
./node_modules/.bin/npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
cd src/extensions/npm/extensions && npm publish --access=public --tag=$(NPM_RELEASE_TAG)
git restore src/extensions/npm/extensions/package.json
cd packages/extensions && npm publish --access=public --tag=$(NPM_RELEASE_TAG) && git restore package.json
.PHONY: publish-library-npm
publish-library-npm: node_modules build-library-npm
./node_modules/.bin/npm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN}"
npm publish --access=public --tag=$(NPM_RELEASE_TAG)
.PHONY: build-docs
build-docs:
@ -90,7 +98,8 @@ docs: build-docs
.PHONY: clean-npm
clean-npm:
rm -rf src/extensions/npm/extensions/{dist,__mocks__,node_modules}
rm -rf packages/extensions/{dist,__mocks__,node_modules}
rm -rf static/build/library/
.PHONY: clean
clean: clean-npm

View File

@ -208,7 +208,7 @@ async function main() {
noTTYOutput: true,
format: "[{bar}] {percentage}% | {downloadArch} {binaryName}",
});
const baseDir = path.join(__dirname, "..", "binaries", "client");
const baseDir = path.join(process.cwd(), "binaries", "client");
const downloaders: BinaryDownloader[] = [
new LensK8sProxyDownloader(deps, {
version: packageInfo.config.k8sProxyVersion,

View File

@ -10,9 +10,9 @@ import sharp from "sharp";
const size = Number(process.env.OUTPUT_SIZE || "16");
const outputFolder = process.env.OUTPUT_DIR || "./static/build/tray";
const inputFile = process.env.INPUT_SVG_PATH || "./src/renderer/components/icon/logo-lens.svg";
const noticeFile = process.env.NOTICE_SVG_PATH || "./src/renderer/components/icon/notice.svg";
const spinnerFile = process.env.SPINNER_SVG_PATH || "./src/renderer/components/icon/arrow-spinner.svg";
const inputFile = process.env.INPUT_SVG_PATH || path.resolve(__dirname, "../src/renderer/components/icon/logo-lens.svg");
const noticeFile = process.env.NOTICE_SVG_PATH || path.resolve(__dirname, "../src/renderer/components/icon/notice.svg");
const spinnerFile = process.env.SPINNER_SVG_PATH || path.resolve(__dirname, "../src/renderer/components/icon/arrow-spinner.svg");
async function ensureOutputFoler() {
await ensureDir(outputFolder);

View File

@ -4,7 +4,7 @@
*/
import * as fs from "fs";
import * as path from "path";
import packageInfo from "../src/extensions/npm/extensions/package.json";
import packageInfo from "../packages/extensions/package.json";
import appInfo from "../package.json";
import { SemVer } from "semver";
import { execSync } from "child_process";
@ -22,4 +22,4 @@ if (NPM_RELEASE_TAG !== "latest") {
packageInfo.version = version.format();
fs.writeFileSync(path.join(__dirname, "../src/extensions/npm/extensions/package.json"), `${JSON.stringify(packageInfo, null, 2)}\n`);
fs.writeFileSync(path.join(__dirname, "../packages/extensions/package.json"), `${JSON.stringify(packageInfo, null, 2)}\n`);

View File

@ -1,16 +1,51 @@
{
"name": "open-lens",
"name": "@k8slens/open-lens",
"productName": "OpenLens",
"description": "OpenLens - Open Source IDE for Kubernetes",
"homepage": "https://github.com/lensapp/lens",
"version": "6.4.0-alpha.0",
"repository": {
"type": "git",
"url": "git+https://github.com/lensapp/lens.git"
},
"keywords": [],
"bugs": {
"url": "https://github.com/lensapp/lens/issues"
},
"main": "static/build/main.js",
"exports": {
"./main": "./static/build/library/main.js",
"./renderer": "./static/build/library/renderer.js",
"./common": "./static/build/library/common.js",
"./styles": "./static/build/library/renderer.css"
},
"typesVersions": {
"*": {
"main": [
"./src/main/library.ts"
],
"renderer": [
"./src/renderer/library.ts"
],
"common": [
"./src/common/library.ts"
]
}
},
"files": [
"build/download_binaries.ts",
"build/*.plist",
"build/installer.nsh",
"build/notarize.js",
"src/**/*",
"static/build/library/**/*",
"templates/**/*",
"types/*",
"tsconfig.json"
],
"copyright": "© 2022 OpenLens Authors",
"license": "MIT",
"author": {
"name": "OpenLens Authors",
"email": "info@k8slens.dev"
},
"author": "OpenLens Authors <info@k8slens.dev>",
"scripts": {
"adr:create": "echo \"What is the title?\"; read title; adr new \"$title\"",
"adr:change-status": "echo \"Decision number?:\"; read decision; adr status $decision",
@ -22,13 +57,14 @@
"dev-run": "nodemon --watch ./static/build/main.js --exec \"electron --remote-debugging-port=9223 --inspect .\"",
"dev:main": "yarn run compile:main --watch --progress",
"dev:renderer": "yarn run ts-node webpack/dev-server.ts",
"compile-library": "env NODE_ENV=production yarn run webpack --config webpack/library-bundle.ts",
"compile": "env NODE_ENV=production concurrently yarn:compile:*",
"compile:main": "yarn run webpack --config webpack/main.ts",
"compile:renderer": "yarn run webpack --config webpack/renderer.ts",
"compile:extension-types": "yarn run webpack --config webpack/extensions.ts",
"compile:node-fetch": "yarn run webpack --config ./webpack/node-fetch.ts",
"postinstall": "yarn run compile:node-fetch",
"npm:fix-package-version": "yarn run ts-node build/set_npm_version.ts",
"prepare": "yarn run compile:node-fetch",
"npm:fix-extensions-package-version": "yarn run ts-node build/set_extensions_npm_version.ts",
"build:linux": "yarn run compile && electron-builder --linux --dir",
"build:mac": "yarn run compile && electron-builder --mac --dir",
"build:win": "yarn run compile && electron-builder --win --dir",
@ -79,7 +115,7 @@
},
"modulePathIgnorePatterns": [
"<rootDir>/dist",
"<rootDir>/src/extensions/npm"
"<rootDir>/packages"
],
"setupFiles": [
"<rootDir>/src/jest.setup.ts",
@ -106,6 +142,7 @@
"LICENSE"
],
"linux": {
"executableName": "open-lens",
"category": "Network",
"artifactName": "${productName}-${version}.${arch}.${ext}",
"target": [
@ -134,6 +171,7 @@
]
},
"mac": {
"executableName": "OpenLens",
"hardenedRuntime": true,
"gatekeeperAssess": false,
"entitlements": "build/entitlements.mac.plist",
@ -154,6 +192,7 @@
]
},
"win": {
"executableName": "OpenLens.exe",
"target": [
"nsis"
],
@ -204,7 +243,6 @@
"@sentry/electron": "^3.0.8",
"@sentry/integrations": "^6.19.3",
"@side/jest-runtime": "^1.0.1",
"@types/circular-dependency-plugin": "5.0.5",
"abort-controller": "^3.0.0",
"auto-bind": "^4.0.0",
"await-lock": "^2.2.2",
@ -238,8 +276,6 @@
"mock-fs": "^5.2.0",
"moment": "^2.29.4",
"moment-timezone": "^0.5.40",
"monaco-editor": "^0.29.1",
"monaco-editor-webpack-plugin": "^5.0.0",
"node-fetch": "^3.3.0",
"node-pty": "0.10.1",
"npm": "^8.19.3",
@ -375,6 +411,8 @@
"memorystream": "^0.3.1",
"mini-css-extract-plugin": "^2.7.2",
"mock-http": "^1.1.0",
"monaco-editor": "^0.29.1",
"monaco-editor-webpack-plugin": "^5.0.0",
"node-gyp": "^8.3.0",
"node-loader": "^2.0.0",
"nodemon": "^2.0.20",
@ -411,5 +449,26 @@
"webpack-node-externals": "^3.0.0",
"xterm": "^4.19.0",
"xterm-addon-fit": "^0.5.0"
},
"peerDependencies": {
"@types/byline": "^4.2.33",
"@types/chart.js": "^2.9.36",
"@types/color": "^3.0.3",
"@types/crypto-js": "^3.1.47",
"@types/lodash": "^4.14.191",
"@types/proper-lockfile": "^4.1.2",
"@types/react-dom": "^17.0.16",
"@types/react-router-dom": "^5.3.3",
"@types/react-virtualized-auto-sizer": "^1.0.1",
"@types/react-window": "^1.8.5",
"@types/request-promise-native": "^1.0.18",
"@types/tar": "^6.1.3",
"@types/tcp-port-used": "^1.0.1",
"@types/url-parse": "^1.4.8",
"@types/uuid": "^8.3.4",
"monaco-editor": "^0.29.1",
"react-select": "^5.7.0",
"typed-emitter": "^1.4.0",
"xterm-addon-fit": "^0.5.0"
}
}

View File

@ -3,12 +3,12 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import applicationInformationInjectable from "../../../vars/application-information.injectable";
import applicationInformationToken from "../../../vars/application-information-token";
const welcomeRouteConfigInjectable = getInjectable({
id: "welcome-route-config",
instantiate: (di) => di.inject(applicationInformationInjectable).config.welcomeRoute,
instantiate: (di) => di.inject(applicationInformationToken).config.welcomeRoute,
});
export default welcomeRouteConfigInjectable;

14
src/common/library.ts Normal file
View File

@ -0,0 +1,14 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import applicationInformationToken from "./vars/application-information-token";
import type { ApplicationInformation } from "./vars/application-information-token";
import { bundledExtensionInjectionToken } from "../extensions/extension-discovery/bundled-extension-token";
// @experimental
export {
applicationInformationToken,
ApplicationInformation,
bundledExtensionInjectionToken,
};

View File

@ -8,15 +8,11 @@ const environmentVariablesInjectable = getInjectable({
id: "environment-variables",
instantiate: () => {
// IMPORTANT: The syntax needs to be exactly this in order to make environment variable values
// hard-coded at compile-time by Webpack.
const NODE_ENV = process.env.NODE_ENV;
const JEST_WORKER_ID = process.env.JEST_WORKER_ID;
const CICD = process.env.CICD;
return {
// Compile-time environment variables
NODE_ENV,
JEST_WORKER_ID,
CICD,

View File

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

View File

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

View File

@ -4,14 +4,12 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import packageJson from "../../../package.json";
export type ApplicationInformation = Pick<typeof packageJson, "version" | "config" | "productName" | "copyright" | "description" | "name"> & {
build: Partial<typeof packageJson["build"]> & { publish?: unknown[] };
};
import applicationInformationToken from "../../common/vars/application-information-token";
const applicationInformationInjectable = getInjectable({
id: "application-information",
instantiate: (): ApplicationInformation => {
injectionToken: applicationInformationToken,
instantiate: () => {
const { version, config, productName, build, copyright, description, name } = packageJson;
return { version, config, productName, build, copyright, description, name };

View File

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

View File

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

View File

@ -3,11 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import applicationInformationInjectable from "./application-information.injectable";
import applicationInformationToken from "./application-information-token";
const contentSecurityPolicyInjectable = getInjectable({
id: "content-security-policy",
instantiate: (di) => di.inject(applicationInformationInjectable).config.contentSecurityPolicy,
instantiate: (di) => di.inject(applicationInformationToken).config.contentSecurityPolicy,
});
export default contentSecurityPolicyInjectable;

View File

@ -4,12 +4,12 @@
*/
import { getInjectable } from "@ogre-tools/injectable";
import { SemVer } from "semver";
import applicationInformationInjectable from "./application-information.injectable";
import applicationInformationToken from "./application-information-token";
const extensionApiVersionInjectable = getInjectable({
id: "extension-api-version",
instantiate: (di) => {
const { major, minor, patch } = new SemVer(di.inject(applicationInformationInjectable).version);
const { major, minor, patch } = new SemVer(di.inject(applicationInformationToken).version);
return `${major}.${minor}.${patch}`;
},

View File

@ -3,13 +3,13 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import environmentVariablesInjectable from "../utils/environment-variables.injectable";
import nodeEnvInjectionToken from "./node-env-injection-token";
const isProductionInjectable = getInjectable({
id: "is-production",
instantiate: (di) => {
const { NODE_ENV: nodeEnv } = di.inject(environmentVariablesInjectable);
const nodeEnv = di.inject(nodeEnvInjectionToken);
return nodeEnv === "production";
},

View File

@ -0,0 +1,11 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectionToken } from "@ogre-tools/injectable";
const nodeEnvInjectionToken = getInjectionToken<string | undefined>({
id: "node-env-injection-token",
});
export default nodeEnvInjectionToken;

View File

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

View File

@ -3,11 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import applicationInformationInjectable from "./application-information.injectable";
import applicationInformationToken from "./application-information-token";
const sentryDataSourceNameInjectable = getInjectable({
id: "sentry-data-source-name",
instantiate: (di) => di.inject(applicationInformationInjectable).config.sentryDsn,
instantiate: (di) => di.inject(applicationInformationToken).config.sentryDsn,
});
export default sentryDataSourceNameInjectable;

View File

@ -5,5 +5,4 @@
import { getGlobalOverride } from "../test-utils/get-global-override";
import staticFilesDirectoryInjectable from "./static-files-directory.injectable";
export default getGlobalOverride(staticFilesDirectoryInjectable, () => "/some-static-directory");

View File

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

View File

@ -404,7 +404,7 @@ export class ExtensionLoader {
const extAbsolutePath = this.dependencies.joinPaths(this.dependencies.getDirnameOfPath(extension.manifestPath), extRelativePath);
try {
return __non_webpack_require__(extAbsolutePath).default;
return require(/* webpackIgnore: true */ extAbsolutePath).default;
} catch (error) {
const message = (error instanceof Error ? error.stack : undefined) || error;

View File

@ -3,11 +3,11 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import applicationInformationInjectable from "../../../../../common/vars/application-information.injectable";
import applicationInformationToken from "../../../../../common/vars/application-information-token";
const publishIsConfiguredInjectable = getInjectable({
id: "publish-is-configured",
instantiate: (di) => Boolean(di.inject(applicationInformationInjectable).build.publish?.length),
instantiate: (di) => Boolean(di.inject(applicationInformationToken).build.publish?.length),
});
export default publishIsConfiguredInjectable;

View File

@ -6,7 +6,7 @@
// Fix embedded kubeconfig paths under snap config
import { getInjectable } from "@ogre-tools/injectable";
import applicationInformationInjectable from "../../../common/vars/application-information.injectable";
import applicationInformationToken from "../../../common/vars/application-information-token";
import { clusterStoreMigrationInjectionToken } from "../../../common/cluster-store/migration-token";
import loggerInjectable from "../../../common/logger.injectable";
import isSnapPackageInjectable from "../../../common/vars/is-snap-package.injectable";
@ -16,7 +16,7 @@ import pathExistsSyncInjectable from "../../../common/fs/path-exists-sync.inject
const clusterStoreSnapMigrationInjectable = getInjectable({
id: "cluster-store-snap-migration",
instantiate: (di) => {
const { version } = di.inject(applicationInformationInjectable);
const { version } = di.inject(applicationInformationToken);
const logger = di.inject(loggerInjectable);
const isSnapPackage = di.inject(isSnapPackageInjectable);
const pathExistsSync = di.inject(pathExistsSyncInjectable);

36
src/main/create-app.ts Normal file
View File

@ -0,0 +1,36 @@
/**
* 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 { getInjectable } from "@ogre-tools/injectable";
import { runInAction } from "mobx";
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
import { registerInjectables } from "./register-injectables";
import startMainApplicationInjectable from "./start-main-application/start-main-application.injectable";
interface AppConfig {
di: DiContainer;
mode: string;
}
export function createApp(conf: AppConfig) {
const { di, mode } = conf;
runInAction(() => {
di.register(getInjectable({
id: "node-env",
instantiate: () => mode,
injectionToken: nodeEnvInjectionToken,
}));
registerInjectables(di);
});
const startMainApplication = di.inject(startMainApplicationInjectable);
return {
start: () => startMainApplication(),
};
}

View File

@ -3,6 +3,7 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import nodeEnvInjectionToken from "../../../common/vars/node-env-injection-token";
import loggerInjectable from "../../../common/logger.injectable";
import { onLoadOfApplicationInjectionToken } from "../../start-main-application/runnable-tokens/on-load-of-application-injection-token";
@ -11,11 +12,12 @@ const setupDeveloperToolsInDevelopmentEnvironmentInjectable = getInjectable({
instantiate: (di) => {
const logger = di.inject(loggerInjectable);
const nodeEnv = di.inject(nodeEnvInjectionToken);
return {
id: "setup-developer-tools-in-development-environment",
run: () => {
if (process.env.NODE_ENV !== "development") {
if (nodeEnv !== "development") {
return;
}

26
src/main/extension-api.ts Normal file
View File

@ -0,0 +1,26 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import * as Mobx from "mobx";
import { spawn } from "node-pty";
import * as LensExtensionsCommonApi from "../extensions/common-api";
import * as LensExtensionsMainApi from "../extensions/main-api";
/**
* Exports for virtual package "@k8slens/extensions" for main-process.
* All exporting names available in global runtime scope:
* e.g. global.Mobx, global.LensExtensions
*/
const LensExtensions = {
Common: LensExtensionsCommonApi,
Main: LensExtensionsMainApi,
};
const Pty = {
spawn,
};
export { Mobx, LensExtensions, Pty };

View File

@ -3,28 +3,14 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { createContainer } from "@ogre-tools/injectable";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import { runInAction } from "mobx";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import applicationInformationInjectable from "../common/vars/application-information-injectable";
export const getDi = () => {
const di = createContainer("main");
setLegacyGlobalDiForExtensionApi(di, Environments.main);
runInAction(() => {
registerMobX(di);
autoRegister({
di,
requireContexts: [
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../features", true, CONTEXT_MATCHER_FOR_FEATURES),
],
});
di.register(applicationInformationInjectable);
});
return di;

View File

@ -5,7 +5,7 @@
import { kebabCase, noop, chunk } from "lodash/fp";
import type { DiContainer, Injectable } from "@ogre-tools/injectable";
import { createContainer, isInjectable } from "@ogre-tools/injectable";
import { createContainer, isInjectable, getInjectable } from "@ogre-tools/injectable";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import writeJsonFileInjectable from "../common/fs/write-json-file.injectable";
import readJsonFileInjectable from "../common/fs/read-json-file.injectable";
@ -71,6 +71,8 @@ import kubectlDownloadingNormalizedArchInjectable from "./kubectl/normalized-arc
import initializeClusterManagerInjectable from "./cluster/initialize-manager.injectable";
import addKubeconfigSyncAsEntitySourceInjectable from "./start-main-application/runnables/kube-config-sync/add-source.injectable";
import type { GlobalOverride } from "../common/test-utils/get-global-override";
import applicationInformationInjectable from "../common/vars/application-information-injectable";
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {}) {
const {
@ -79,6 +81,12 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
const di = createContainer("main");
di.register(getInjectable({
id: "node-env",
instantiate: () => "test",
injectionToken: nodeEnvInjectionToken,
}));
setLegacyGlobalDiForExtensionApi(di, Environments.main);
di.preventSideEffects();
@ -93,6 +101,7 @@ export function getDiForUnitTesting(opts: { doGeneralOverrides?: boolean } = {})
runInAction(() => {
registerMobX(di);
di.register(applicationInformationInjectable);
chunk(100)(injectables).forEach(chunkInjectables => {
di.register(...chunkInjectables);

View File

@ -5,38 +5,19 @@
// Main process
import * as Mobx from "mobx";
import { spawn } from "node-pty";
import process from "process";
import * as LensExtensionsCommonApi from "../extensions/common-api";
import * as LensExtensionsMainApi from "../extensions/main-api";
import { getDi } from "./getDi";
import startMainApplicationInjectable from "./start-main-application/start-main-application.injectable";
import { Mobx, LensExtensions, Pty } from "./extension-api";
import { createApp } from "./create-app";
const di = getDi();
const startMainApplication = di.inject(startMainApplicationInjectable);
const app = createApp({
di,
mode: process.env.NODE_ENV || "development",
});
(async () => {
try {
await startMainApplication();
} catch (error) {
app.start().catch((error) => {
console.error(error);
process.exit(1);
}
})();
/**
* Exports for virtual package "@k8slens/extensions" for main-process.
* All exporting names available in global runtime scope:
* e.g. global.Mobx, global.LensExtensions
*/
const LensExtensions = {
Common: LensExtensionsCommonApi,
Main: LensExtensionsMainApi,
};
const Pty = {
spawn,
};
});
export { Mobx, LensExtensions, Pty };

21
src/main/library.ts Normal file
View File

@ -0,0 +1,21 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { afterApplicationIsLoadedInjectionToken } from "./start-main-application/runnable-tokens/after-application-is-loaded-injection-token";
import { beforeApplicationIsLoadingInjectionToken } from "./start-main-application/runnable-tokens/before-application-is-loading-injection-token";
import { beforeElectronIsReadyInjectionToken } from "./start-main-application/runnable-tokens/before-electron-is-ready-injection-token";
import { onLoadOfApplicationInjectionToken } from "./start-main-application/runnable-tokens/on-load-of-application-injection-token";
import * as extensionApi from "./extension-api";
import { createApp } from "./create-app";
// @experimental
export {
createApp,
extensionApi,
afterApplicationIsLoadedInjectionToken,
beforeApplicationIsLoadingInjectionToken,
beforeElectronIsReadyInjectionToken,
onLoadOfApplicationInjectionToken,
};

View File

@ -0,0 +1,29 @@
/**
* 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 { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import { runInAction } from "mobx";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
export function registerInjectables(di: DiContainer) {
setLegacyGlobalDiForExtensionApi(di, Environments.main);
runInAction(() => {
registerMobX(di);
autoRegister({
di,
requireContexts: [
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../features", true, CONTEXT_MATCHER_FOR_FEATURES),
],
});
});
return di;
}

View File

@ -6,19 +6,17 @@ import { getInjectable } from "@ogre-tools/injectable";
import httpProxy from "http-proxy";
import { webpackDevServerPort } from "../../../../webpack/vars";
import { publicPath } from "../../../common/vars";
import appNameInjectable from "../../../common/vars/app-name.injectable";
import type { LensApiRequest, RouteResponse } from "../../router/route";
const devStaticFileRouteHandlerInjectable = getInjectable({
id: "dev-static-file-route-handler",
instantiate: (di) => {
instantiate: () => {
const proxy = httpProxy.createProxy();
const appName = di.inject(appNameInjectable);
const proxyTarget = `http://127.0.0.1:${webpackDevServerPort}`;
return async ({ raw: { req, res }}: LensApiRequest<"/{path*}">): Promise<RouteResponse<Buffer>> => {
if (req.url === "/" || !req.url) {
req.url = `${publicPath}/${appName}.html`;
req.url = `${publicPath}/index.html`;
} else if (!req.url.startsWith("/build/")) {
return { statusCode: 404 };
}

View File

@ -6,7 +6,6 @@ import { getInjectable } from "@ogre-tools/injectable";
import readFileBufferInjectable from "../../../common/fs/read-file-buffer.injectable";
import joinPathsInjectable from "../../../common/path/join-paths.injectable";
import staticFilesDirectoryInjectable from "../../../common/vars/static-files-directory.injectable";
import appNameInjectable from "../../../common/vars/app-name.injectable";
import type { LensApiRequest } from "../../router/route";
import path from "path";
import type { SupportedFileExtension } from "../../router/router-content-types";
@ -20,7 +19,6 @@ const prodStaticFileRouteHandlerInjectable = getInjectable({
const readFileBuffer = di.inject(readFileBufferInjectable);
const joinPaths = di.inject(joinPathsInjectable);
const staticFilesDirectory = di.inject(staticFilesDirectoryInjectable);
const appName = di.inject(appNameInjectable);
const logger = di.inject(loggerInjectable);
return async ({ params }: LensApiRequest<"/{path*}">) => {
@ -49,7 +47,7 @@ const prodStaticFileRouteHandlerInjectable = getInjectable({
return { statusCode: 404 };
}
filePath = `${publicPath}/${appName}.html`;
filePath = `${publicPath}/index.html`;
}
}

View File

@ -12,7 +12,7 @@ import openLinkInBrowserInjectable from "../../../../common/utils/open-link-in-b
import getAbsolutePathInjectable from "../../../../common/path/get-absolute-path.injectable";
import lensResourcesDirInjectable from "../../../../common/vars/lens-resources-dir.injectable";
import isLinuxInjectable from "../../../../common/vars/is-linux.injectable";
import applicationInformationInjectable from "../../../../common/vars/application-information.injectable";
import applicationInformationToken from "../../../../common/vars/application-information-token";
import pathExistsSyncInjectable from "../../../../common/fs/path-exists-sync.injectable";
@ -54,7 +54,7 @@ const createElectronWindowInjectable = getInjectable({
const getAbsolutePath = di.inject(getAbsolutePathInjectable);
const lensResourcesDir = di.inject(lensResourcesDirInjectable);
const isLinux = di.inject(isLinuxInjectable);
const applicationInformation = di.inject(applicationInformationInjectable);
const applicationInformation = di.inject(applicationInformationToken);
const pathExistsSync = di.inject(pathExistsSyncInjectable);
return (configuration) => {

View File

@ -3,14 +3,14 @@
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getGlobalOverride } from "../test-utils/get-global-override";
import applicationInformationInjectable from "./application-information.injectable";
import { getGlobalOverride } from "../../common/test-utils/get-global-override";
import applicationInformationInjectable from "../../common/vars/application-information-injectable";
export default getGlobalOverride(applicationInformationInjectable, () => ({
name: "some-product-name",
productName: "some-product-name",
version: "6.0.0",
build: {},
build: {} as any,
config: {
k8sProxyVersion: "0.2.1",
bundledKubectlVersion: "1.23.3",
@ -18,7 +18,6 @@ export default getGlobalOverride(applicationInformationInjectable, () => ({
sentryDsn: "",
contentSecurityPolicy: "script-src 'unsafe-eval' 'self'; frame-src http://*.localhost:*/; img-src * data:",
welcomeRoute: "/welcome",
extensions: [],
},
copyright: "some-copyright-information",
description: "some-descriptive-text",

View File

@ -7,13 +7,13 @@ import { docsUrl, slackUrl } from "../../../common/vars";
import type { WeblinkData } from "../../../common/weblinks-store/weblink-store";
import { getInjectable } from "@ogre-tools/injectable";
import { weblinkStoreMigrationInjectionToken } from "../../../common/weblinks-store/migration-token";
import applicationInformationInjectable from "../../../common/vars/application-information.injectable";
import applicationInformationToken from "../../../common/vars/application-information-token";
import { lensDocumentationWeblinkId, lensSlackWeblinkId } from "../links";
const currentVersionWeblinkStoreMigrationInjectable = getInjectable({
id: "current-version-weblink-store-migration",
instantiate: (di) => {
const { version } = di.inject(applicationInformationInjectable);
const { version } = di.inject(applicationInformationToken);
return {
version, // Run always after upgrade

View File

@ -6,15 +6,8 @@
import "./components/app.scss";
import React from "react";
import ReactDOM, { render, unmountComponentAtNode } from "react-dom";
import * as Mobx from "mobx";
import * as MobxReact from "mobx-react";
import * as ReactRouter from "react-router";
import * as ReactRouterDom from "react-router-dom";
import * as LensExtensionsCommonApi from "../extensions/common-api";
import * as LensExtensionsRendererApi from "../extensions/renderer-api";
import { render, unmountComponentAtNode } from "react-dom";
import { DefaultProps } from "./mui-base-theme";
import { getDi } from "./getDi";
import { DiContextProvider } from "@ogre-tools/injectable-react";
import type { DiContainer } from "@ogre-tools/injectable";
import extensionLoaderInjectable from "../extensions/extension-loader/extension-loader.injectable";
@ -80,28 +73,3 @@ export async function bootstrap(di: DiContainer) {
rootElem,
);
}
const di = getDi();
// run
bootstrap(di);
/**
* Exports for virtual package "@k8slens/extensions" for renderer-process.
* All exporting names available in global runtime scope:
* e.g. Devtools -> Console -> window.LensExtensions (renderer)
*/
const LensExtensions = {
Common: LensExtensionsCommonApi,
Renderer: LensExtensionsRendererApi,
};
export {
React,
ReactDOM,
ReactRouter,
ReactRouterDom,
Mobx,
MobxReact,
LensExtensions,
};

View File

@ -0,0 +1,34 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import "./components/app.scss";
import { bootstrap } from "./bootstrap";
import type { DiContainer } from "@ogre-tools/injectable";
import { getInjectable } from "@ogre-tools/injectable";
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
import { runInAction } from "mobx";
import { registerInjectables } from "./register-injectables";
interface AppConfig {
di: DiContainer;
mode: string;
}
export function createApp(conf: AppConfig) {
const { di, mode } = conf;
runInAction(() => {
di.register(getInjectable({
id: "node-env",
instantiate: () => mode,
injectionToken: nodeEnvInjectionToken,
}));
registerInjectables(di);
});
return {
start: () => bootstrap(di),
};
}

View File

@ -0,0 +1,33 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import React from "react";
import ReactDOM from "react-dom";
import * as Mobx from "mobx";
import * as MobxReact from "mobx-react";
import * as ReactRouter from "react-router";
import * as ReactRouterDom from "react-router-dom";
import * as LensExtensionsCommonApi from "../extensions/common-api";
import * as LensExtensionsRendererApi from "../extensions/renderer-api";
/**
* Exports for virtual package "@k8slens/extensions" for renderer-process.
* All exporting names available in global runtime scope:
* e.g. Devtools -> Console -> window.LensExtensions (renderer)
*/
const LensExtensions = {
Common: LensExtensionsCommonApi,
Renderer: LensExtensionsRendererApi,
};
export {
React,
ReactDOM,
ReactRouter,
ReactRouterDom,
Mobx,
MobxReact,
LensExtensions,
};

View File

@ -9,30 +9,25 @@ import { MainLayout } from "../../components/layout/main-layout";
import { Sidebar } from "../../components/layout/sidebar";
import { Dock } from "../../components/dock";
import styles from "./cluster-frame.module.css";
import type { IComputedValue } from "mobx";
import { computed } from "mobx";
import currentRouteComponentInjectable from "../../routes/current-route-component.injectable";
import { Redirect } from "react-router";
import startUrlInjectable from "./start-url.injectable";
import currentPathInjectable from "../../routes/current-path.injectable";
import { observer } from "mobx-react";
import { withInjectables } from "@ogre-tools/injectable-react";
const clusterFrameLayoutChildComponentInjectable = getInjectable({
id: "cluster-frame-layout-child-component",
interface Dependencies {
currentRouteComponent: IComputedValue<React.ElementType<any> | undefined>;
startUrl: IComputedValue<string>;
currentPath: IComputedValue<string>;
}
instantiate: (di) => {
const currentRouteComponent = di.inject(currentRouteComponentInjectable);
const startUrl = di.inject(startUrlInjectable);
const currentPath = di.inject(currentPathInjectable);
return {
id: "cluster-frame-layout",
shouldRender: computed(() => true),
Component: observer(() => {
const Component = currentRouteComponent.get();
const starting = startUrl.get();
const current = currentPath.get();
const NonInjectedClusterFrameLayout = observer((props: Dependencies) => {
const Component = props.currentRouteComponent.get();
const starting = props.startUrl.get();
const current = props.currentPath.get();
return (
<MainLayout sidebar={<Sidebar />} footer={<Dock />}>
@ -40,7 +35,7 @@ const clusterFrameLayoutChildComponentInjectable = getInjectable({
<Component />
) : // NOTE: this check is to prevent an infinite loop
starting !== current ? (
<Redirect to={startUrl.get()} />
<Redirect to={starting} />
) : (
<div className={styles.centering}>
<div className="error">
@ -51,9 +46,25 @@ const clusterFrameLayoutChildComponentInjectable = getInjectable({
)}
</MainLayout>
);
});
const ClusterFrameLayout = withInjectables<Dependencies>(NonInjectedClusterFrameLayout, {
getProps: (di, props) => ({
...props,
currentRouteComponent: di.inject(currentRouteComponentInjectable),
startUrl: di.inject(startUrlInjectable),
currentPath: di.inject(currentPathInjectable),
}),
});
const clusterFrameLayoutChildComponentInjectable = getInjectable({
id: "cluster-frame-layout-child-component",
instantiate: () => ({
id: "cluster-frame-layout",
shouldRender: computed(() => true),
Component: ClusterFrameLayout,
}),
};
},
injectionToken: clusterFrameChildComponentInjectionToken,
});

View File

@ -4,28 +4,14 @@
*/
import { createContainer } from "@ogre-tools/injectable";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import { runInAction } from "mobx";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import applicationInformationInjectable from "../common/vars/application-information-injectable";
export const getDi = () => {
const di = createContainer("renderer");
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
runInAction(() => {
registerMobX(di);
autoRegister({
di,
requireContexts: [
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../features", true, CONTEXT_MATCHER_FOR_FEATURES),
],
});
di.register(applicationInformationInjectable);
});
return di;

View File

@ -5,7 +5,7 @@
import { noop, chunk } from "lodash/fp";
import type { DiContainer, Injectable } from "@ogre-tools/injectable";
import { createContainer, isInjectable } from "@ogre-tools/injectable";
import { createContainer, isInjectable, getInjectable } from "@ogre-tools/injectable";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
import requestFromChannelInjectable from "./utils/channel/request-from-channel.injectable";
import loggerInjectable from "../common/logger.injectable";
@ -41,6 +41,8 @@ import legacyOnChannelListenInjectable from "./ipc/legacy-channel-listen.injecta
import storageSaveDelayInjectable from "./utils/create-storage/storage-save-delay.injectable";
import environmentVariablesInjectable from "../common/utils/environment-variables.injectable";
import type { GlobalOverride } from "../common/test-utils/get-global-override";
import applicationInformationInjectable from "../common/vars/application-information-injectable";
import nodeEnvInjectionToken from "../common/vars/node-env-injection-token";
export const getDiForUnitTesting = (
opts: { doGeneralOverrides?: boolean } = {},
@ -49,6 +51,12 @@ export const getDiForUnitTesting = (
const di = createContainer("renderer");
di.register(getInjectable({
id: "node-env",
instantiate: () => "test",
injectionToken: nodeEnvInjectionToken,
}));
di.preventSideEffects();
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
@ -63,6 +71,7 @@ export const getDiForUnitTesting = (
runInAction(() => {
registerMobX(di);
di.register(applicationInformationInjectable);
chunk(100)(injectables).forEach((chunkInjectables) => {
di.register(...chunkInjectables);

32
src/renderer/index.ts Normal file
View File

@ -0,0 +1,32 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import "./components/app.scss";
import { getDi } from "./getDi";
import {
React, ReactDOM, ReactRouter,
ReactRouterDom, Mobx, MobxReact, LensExtensions,
} from "./extension-api";
import { createApp } from "./create-app";
const di = getDi();
const app = createApp({
di,
mode: process.env.NODE_ENV || "development",
});
// run
app.start();
export {
React,
ReactDOM,
ReactRouter,
ReactRouterDom,
Mobx,
MobxReact,
LensExtensions,
};

14
src/renderer/library.ts Normal file
View File

@ -0,0 +1,14 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import "./components/app.scss";
import * as extensionApi from "./extension-api";
import { createApp } from "./create-app";
// @experimental
export {
createApp,
extensionApi,
};

View File

@ -0,0 +1,30 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import type { DiContainer } from "@ogre-tools/injectable";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import { runInAction } from "mobx";
import { Environments, setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
export function registerInjectables(di: DiContainer) {
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
runInAction(() => {
registerMobX(di);
autoRegister({
di,
requireContexts: [
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../common", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../extensions", true, CONTEXT_MATCHER_FOR_NON_FEATURES),
require.context("../features", true, CONTEXT_MATCHER_FOR_FEATURES),
],
});
});
return di;
}

View File

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

109
webpack/library-bundle.ts Normal file
View File

@ -0,0 +1,109 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import { platform } from "os";
import path from "path";
import type { WebpackPluginInstance } from "webpack";
import { DefinePlugin, optimize } from "webpack";
import main from "./main";
import renderer from "./renderer";
import { buildDir } from "./vars";
import CircularDependencyPlugin from "circular-dependency-plugin";
import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin";
const rendererConfig = renderer({ showVars: false });
const config = [
{
...main(),
entry: {
main: path.resolve(__dirname, "..", "src", "main", "library.ts"),
},
output: {
library: {
type: "commonjs2",
},
path: path.resolve(buildDir, "library"),
},
optimization: {
minimize: false,
},
plugins: [
new DefinePlugin({
CONTEXT_MATCHER_FOR_NON_FEATURES: `/\\.injectable(\\.${platform})?\\.tsx?$/`,
CONTEXT_MATCHER_FOR_FEATURES: `/\\/(main|common)\\/.+\\.injectable(\\.${platform})?\\.tsx?$/`,
}),
new CircularDependencyPlugin({
cwd: __dirname,
exclude: /node_modules/,
failOnError: true,
}) as unknown as WebpackPluginInstance,
],
},
{
...rendererConfig,
name: "lens-app-common",
entry: {
common: path.resolve(__dirname, "..", "src", "common", "library.ts"),
},
output: {
library: {
type: "commonjs2",
},
path: path.resolve(buildDir, "library"),
},
optimization: {
minimize: false,
},
plugins: [
new ForkTsCheckerPlugin(),
new CircularDependencyPlugin({
cwd: __dirname,
exclude: /node_modules/,
failOnError: true,
}) as unknown as WebpackPluginInstance,
],
},
{
...rendererConfig,
entry: {
renderer: path.resolve(__dirname, "..", "src", "renderer", "library.ts"),
},
output: {
library: {
type: "commonjs2",
},
path: path.resolve(buildDir, "library"),
},
optimization: {
minimize: false,
},
externals: {
...(rendererConfig.externals as any),
"monaco-editor": "commonjs monaco-editor",
},
plugins: [
new DefinePlugin({
CONTEXT_MATCHER_FOR_NON_FEATURES: `/\\.injectable(\\.${platform})?\\.tsx?$/`,
CONTEXT_MATCHER_FOR_FEATURES: `/\\/(renderer|common)\\/.+\\.injectable(\\.${platform})?\\.tsx?$/`,
}),
new MiniCssExtractPlugin({
filename: "[name].css",
runtime: false,
}),
new optimize.LimitChunkCountPlugin({
maxChunks: 1,
}),
new ForkTsCheckerPlugin(),
new CircularDependencyPlugin({
cwd: __dirname,
exclude: /node_modules/,
failOnError: true,
}) as unknown as WebpackPluginInstance,
],
},
];
export default config;

View File

@ -15,14 +15,14 @@ import { DefinePlugin } from "webpack";
import { buildDir, isDevelopment, mainDir } from "./vars";
import { platform } from "process";
const configs: { (): webpack.Configuration }[] = [];
configs.push((): webpack.Configuration => {
const main = ({ showVars = true } = {}): webpack.Configuration => {
if (showVars) {
console.info("WEBPACK:main", {
isDevelopment,
mainDir,
buildDir,
});
}
return {
name: "lens-app-main",
@ -45,6 +45,11 @@ configs.push((): webpack.Configuration => {
nodeExternals(),
],
module: {
parser: {
javascript: {
commonjsMagicComments: true,
},
},
rules: [
{
test: /\.node$/,
@ -67,6 +72,6 @@ configs.push((): webpack.Configuration => {
}) as unknown as WebpackPluginInstance,
],
};
});
};
export default configs;
export default main;

View File

@ -38,7 +38,7 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura
devtool: isDevelopment ? "cheap-module-source-map" : "source-map",
cache: isDevelopment ? { type: "filesystem" } : false,
entry: {
[appName]: path.resolve(rendererDir, "bootstrap.tsx"),
[appName]: path.resolve(rendererDir, "index.ts"),
},
output: {
libraryTarget: "global",
@ -70,6 +70,11 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura
minimize: false,
},
module: {
parser: {
javascript: {
commonjsMagicComments: true,
},
},
rules: [
{
test: /\.node$/,
@ -102,7 +107,7 @@ export function webpackLensRenderer({ showVars = true } = {}): webpack.Configura
}),
new HtmlWebpackPlugin({
filename: `${appName}.html`,
filename: "index.html",
template: htmlTemplate,
inject: true,
hash: true,

View File

@ -11,7 +11,7 @@ export const isDevelopment = process.env.NODE_ENV !== "production";
export const mainDir = path.join(process.cwd(), "src", "main");
export const buildDir = path.join(process.cwd(), "static", "build");
export const extensionEntry = path.join(process.cwd(), "src", "extensions", "extension-api.ts");
export const extensionOutDir = path.join(process.cwd(), "src", "extensions", "npm", "extensions", "dist");
export const extensionOutDir = path.join(process.cwd(), "packages", "extensions", "dist");
export const assetsFolderName = "assets";
export const rendererDir = path.join(process.cwd(), "src", "renderer");
export const appName = isDevelopment

View File

@ -8415,9 +8415,6 @@ klona@^2.0.4, klona@^2.0.5:
resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc"
integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==
"kube-object-event-status@file:./extensions/kube-object-event-status":
version "6.1.1"
kuler@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3"
@ -8435,15 +8432,6 @@ lazy-val@^1.0.4, lazy-val@^1.0.5:
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.5.tgz#6cf3b9f5bc31cee7ee3e369c0832b7583dcd923d"
integrity sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==
"lens-metrics-cluster-feature@file:./extensions/metrics-cluster-feature":
version "6.1.0"
"lens-node-menu@file:./extensions/node-menu":
version "6.1.0"
"lens-pod-menu@file:./extensions/pod-menu":
version "6.1.0"
less@^4.1.1:
version "4.1.2"
resolved "https://registry.yarnpkg.com/less/-/less-4.1.2.tgz#6099ee584999750c2624b65f80145f8674e4b4b0"
@ -9004,9 +8992,6 @@ methods@~1.1.2:
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
"metrics-cluster-feature@file:./extensions/metrics-cluster-feature":
version "6.1.0"
micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
@ -9453,9 +9438,6 @@ node-loader@^2.0.0:
dependencies:
loader-utils "^2.0.0"
"node-menu@file:./extensions/node-menu":
version "6.1.0"
node-pty@0.10.1:
version "0.10.1"
resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.10.1.tgz#cd05d03a2710315ec40221232ec04186f6ac2c6d"
@ -10261,9 +10243,6 @@ plist@^3.0.1, plist@^3.0.4:
base64-js "^1.5.1"
xmlbuilder "^9.0.7"
"pod-menu@file:./extensions/pod-menu":
version "6.1.0"
popper.js@1.16.1-lts:
version "1.16.1-lts"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1-lts.tgz#cf6847b807da3799d80ee3d6d2f90df8a3f50b05"