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

Merge branch 'master' into dependabot/npm_and_yarn/swc/core-1.3.37

This commit is contained in:
Alex Andreev 2023-03-03 11:51:56 +03:00
commit 405b1c16a5
60 changed files with 17339 additions and 1667 deletions

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

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

View File

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

View File

@ -1,7 +1,7 @@
{ {
"$schema": "node_modules/lerna/schemas/lerna-schema.json", "$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useWorkspaces": true, "useWorkspaces": true,
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"npmClient": "npm", "npmClient": "npm",
"npmClientArgs": [ "npmClientArgs": [
"--network-timeout=100000" "--network-timeout=100000"

17483
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,6 @@
"adr": "^1.4.3", "adr": "^1.4.3",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"lerna": "^6.5.1", "lerna": "^6.5.1",
"rimraf": "^4.1.2" "rimraf": "^4.1.3"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@k8slens/bump-version-for-cron", "name": "@k8slens/bump-version-for-cron",
"version": "6.4.0-cron.4db172da60", "version": "6.5.0-alpha.0",
"description": "CLI to bump the version to during a cron daily alpha release", "description": "CLI to bump the version to during a cron daily alpha release",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {

View File

@ -3,7 +3,7 @@
"productName": "", "productName": "",
"description": "Lens Desktop Core", "description": "Lens Desktop Core",
"homepage": "https://github.com/lensapp/lens", "homepage": "https://github.com/lensapp/lens",
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/lensapp/lens.git" "url": "git+https://github.com/lensapp/lens.git"
@ -127,7 +127,7 @@
"@astronautlabs/jsonpath": "^1.1.0", "@astronautlabs/jsonpath": "^1.1.0",
"@hapi/call": "^9.0.1", "@hapi/call": "^9.0.1",
"@hapi/subtext": "^7.1.0", "@hapi/subtext": "^7.1.0",
"@k8slens/node-fetch": "^6.4.0-beta.13", "@k8slens/node-fetch": "^6.5.0-alpha.0",
"@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": "^15.1.1", "@ogre-tools/fp": "^15.1.1",
@ -329,7 +329,7 @@
"xterm-addon-fit": "^0.5.0" "xterm-addon-fit": "^0.5.0"
}, },
"peerDependencies": { "peerDependencies": {
"@k8slens/application": "^6.4.0-beta.13", "@k8slens/application": "^6.5.0-alpha.0",
"@types/byline": "^4.2.33", "@types/byline": "^4.2.33",
"@types/chart.js": "^2.9.36", "@types/chart.js": "^2.9.36",
"@types/color": "^3.0.3", "@types/color": "^3.0.3",

View File

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

View File

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

View File

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

View File

@ -24,6 +24,7 @@ export const applicationInformationFakeInjectable = getInjectable({
welcomeRoute: "/welcome", welcomeRoute: "/welcome",
copyright: "some-copyright-information", copyright: "some-copyright-information",
description: "some-descriptive-text", description: "some-descriptive-text",
dependencies: {},
}), }),
injectionToken: applicationInformationToken, injectionToken: applicationInformationToken,

View File

@ -0,0 +1,14 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import nodeEnvInjectionToken from "./node-env-injection-token";
const nodeEnvFakeInjectable = getInjectable({
id: "node-env-fake",
instantiate: () => "production",
injectionToken: nodeEnvInjectionToken,
});
export default nodeEnvFakeInjectable;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,21 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import pathToNpmCliInjectable from "../../common/app-paths/path-to-npm-cli.injectable";
import loggerInjectable from "../../common/logger.injectable";
import { ExtensionInstaller } from "./extension-installer";
import extensionPackageRootDirectoryInjectable from "./extension-package-root-directory/extension-package-root-directory.injectable";
const extensionInstallerInjectable = getInjectable({
id: "extension-installer",
instantiate: (di) => new ExtensionInstaller({
extensionPackageRootDirectory: di.inject(extensionPackageRootDirectoryInjectable),
logger: di.inject(loggerInjectable),
pathToNpmCli: di.inject(pathToNpmCliInjectable),
}),
});
export default extensionInstallerInjectable;

View File

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

View File

@ -1,13 +0,0 @@
/**
* Copyright (c) OpenLens Authors. All rights reserved.
* Licensed under MIT License. See LICENSE in root directory for more information.
*/
import { getInjectable } from "@ogre-tools/injectable";
import extensionInstallerInjectable from "../extension-installer.injectable";
const installExtensionInjectable = getInjectable({
id: "install-extension",
instantiate: (di) => di.inject(extensionInstallerInjectable).installPackage,
});
export default installExtensionInjectable;

View File

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

View File

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

View File

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

View File

@ -2,22 +2,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 { applicationInformationToken } from "@k8slens/application";
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import { bundledExtensionInjectionToken } from "../../../../../../common/library"; import { bundledExtensionInjectionToken } from "../../../../../../common/library";
import { object } from "../../../../../../common/utils";
import buildSemanticVersionInjectable from "../../../../../../common/vars/build-semantic-version.injectable"; import buildSemanticVersionInjectable from "../../../../../../common/vars/build-semantic-version.injectable";
const aboutBundledExtensionsInjectable = getInjectable({ const specificVersionsInjectable = getInjectable({
id: "about-bundled-extensions", id: "specific-versions",
instantiate: (di) => { instantiate: (di) => {
const buildSemanticVersion = di.inject(buildSemanticVersionInjectable); const buildSemanticVersion = di.inject(buildSemanticVersionInjectable);
const bundledExtensions = di.injectMany(bundledExtensionInjectionToken); const bundledExtensions = di.injectMany(bundledExtensionInjectionToken);
const applicationInformation = di.inject(applicationInformationToken);
if (buildSemanticVersion.get().prerelease[0] === "latest") { if (buildSemanticVersion.get().prerelease[0] === "latest") {
return []; return [];
} }
return bundledExtensions.map(ext => `${ext.manifest.name}: ${ext.manifest.version}`); const corePackageVersions = object.entries(applicationInformation.dependencies)
.filter(([name]) => name.startsWith("@k8slens/"))
.map(([name, version]) => `${name}: ${version}`);
const bundledExtensionVersions = bundledExtensions
.map(ext => `${ext.manifest.name}: ${ext.manifest.version}`);
return [
...corePackageVersions,
...bundledExtensionVersions,
];
}, },
}); });
export default aboutBundledExtensionsInjectable; export default specificVersionsInjectable;

View File

@ -10,7 +10,7 @@ import productNameInjectable from "../../../../../../common/vars/product-name.in
import buildVersionInjectable from "../../../../../../main/vars/build-version/build-version.injectable"; import buildVersionInjectable from "../../../../../../main/vars/build-version/build-version.injectable";
import extensionApiVersionInjectable from "../../../../../../common/vars/extension-api-version.injectable"; import extensionApiVersionInjectable from "../../../../../../common/vars/extension-api-version.injectable";
import applicationCopyrightInjectable from "../../../../../../common/vars/application-copyright.injectable"; import applicationCopyrightInjectable from "../../../../../../common/vars/application-copyright.injectable";
import aboutBundledExtensionsInjectable from "./about-bundled-extensions.injectable"; import specificVersionsInjectable from "./about-bundled-extensions.injectable";
const showAboutInjectable = getInjectable({ const showAboutInjectable = getInjectable({
id: "show-about", id: "show-about",
@ -23,7 +23,7 @@ const showAboutInjectable = getInjectable({
const appName = di.inject(appNameInjectable); const appName = di.inject(appNameInjectable);
const productName = di.inject(productNameInjectable); const productName = di.inject(productNameInjectable);
const applicationCopyright = di.inject(applicationCopyrightInjectable); const applicationCopyright = di.inject(applicationCopyrightInjectable);
const aboutBundledExtensions = di.inject(aboutBundledExtensionsInjectable); const specificVersions = di.inject(specificVersionsInjectable);
return () => { return () => {
const appInfo = [ const appInfo = [
@ -32,14 +32,26 @@ const showAboutInjectable = getInjectable({
`Electron: ${process.versions.electron}`, `Electron: ${process.versions.electron}`,
`Chrome: ${process.versions.chrome}`, `Chrome: ${process.versions.chrome}`,
`Node: ${process.versions.node}`, `Node: ${process.versions.node}`,
...aboutBundledExtensions,
applicationCopyright, applicationCopyright,
]; ];
if (specificVersions.length > 0) {
appInfo.push(
"",
"",
...specificVersions,
);
}
showMessagePopup( showMessagePopup(
`${isWindows ? " ".repeat(2) : ""}${appName}`, `${isWindows ? " ".repeat(2) : ""}${appName}`,
productName, productName,
appInfo.join("\r\n"), appInfo.join("\r\n"),
{
textWidth: specificVersions.length > 0
? 300
: undefined,
},
); );
}; };
}, },

View File

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

View File

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

View File

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

View File

@ -5,7 +5,11 @@
import { getInjectable } from "@ogre-tools/injectable"; import { getInjectable } from "@ogre-tools/injectable";
import electronDialogInjectable from "./electron-dialog.injectable"; import electronDialogInjectable from "./electron-dialog.injectable";
export type ShowMessagePopup = (title: string, message: string, detail: string) => void; export interface ShowMessagePopupOptions {
textWidth?: number;
}
export type ShowMessagePopup = (title: string, message: string, detail: string, options?: ShowMessagePopupOptions) => void;
const showMessagePopupInjectable = getInjectable({ const showMessagePopupInjectable = getInjectable({
id: "show-message-popup", id: "show-message-popup",
@ -13,13 +17,14 @@ const showMessagePopupInjectable = getInjectable({
instantiate: (di): ShowMessagePopup => { instantiate: (di): ShowMessagePopup => {
const dialog = di.inject(electronDialogInjectable); const dialog = di.inject(electronDialogInjectable);
return async (title, message, detail) => { return async (title, message, detail, options = {}) => {
await dialog.showMessageBox({ await dialog.showMessageBox({
title, title,
message, message,
detail, detail,
type: "info", type: "info",
buttons: ["Close"], buttons: ["Close"],
...options,
}); });
}; };
}, },

View File

@ -3,5 +3,15 @@
* 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 { createContainer } from "@ogre-tools/injectable"; import { createContainer } from "@ogre-tools/injectable";
import { registerMobX } from "@ogre-tools/injectable-extension-for-mobx";
import { setLegacyGlobalDiForExtensionApi } from "../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api";
export const getDi = () => createContainer("main"); export const getDi = () => {
const environment = "main";
const di = createContainer(environment);
registerMobX(di);
setLegacyGlobalDiForExtensionApi(di, environment);
return di;
};

View File

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

View File

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

View File

@ -4,16 +4,10 @@
*/ */
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 { runInAction } from "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) { export function registerInjectables(di: DiContainer) {
setLegacyGlobalDiForExtensionApi(di, Environments.main);
runInAction(() => { runInAction(() => {
registerMobX(di);
autoRegister({ autoRegister({
di, di,
targetModule: module, targetModule: module,
@ -25,6 +19,4 @@ export function registerInjectables(di: DiContainer) {
], ],
}); });
}); });
return di;
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -5,19 +5,10 @@
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 { 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";
export function registerInjectables(di: DiContainer) { export function registerInjectables(di: DiContainer) {
setLegacyGlobalDiForExtensionApi(di, Environments.renderer);
registerMobX(di);
registerInjectableReact(di);
runInAction(() => { runInAction(() => {
autoRegister({ autoRegister({
di, di,
targetModule: module, targetModule: module,
@ -29,6 +20,4 @@ export function registerInjectables(di: DiContainer) {
], ],
}); });
}); });
return di;
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@k8slens/ensure-binaries", "name": "@k8slens/ensure-binaries",
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"description": "CLI for downloading configured versions of the bundled versions of CLIs", "description": "CLI for downloading configured versions of the bundled versions of CLIs",
"main": "dist/index.js", "main": "dist/index.js",
"license": "MIT", "license": "MIT",

View File

@ -2,7 +2,7 @@
"name": "@k8slens/extensions", "name": "@k8slens/extensions",
"productName": "OpenLens extensions", "productName": "OpenLens extensions",
"description": "OpenLens - Open Source Kubernetes IDE: extensions", "description": "OpenLens - Open Source Kubernetes IDE: extensions",
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"copyright": "© 2022 OpenLens Authors", "copyright": "© 2022 OpenLens Authors",
"license": "MIT", "license": "MIT",
"main": "dist/extension-api.js", "main": "dist/extension-api.js",
@ -26,7 +26,7 @@
"prepare:dev": "npm run build" "prepare:dev": "npm run build"
}, },
"dependencies": { "dependencies": {
"@k8slens/core": "^6.4.0-beta.13" "@k8slens/core": "^6.5.0-alpha.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^16.18.6", "@types/node": "^16.18.6",

View File

@ -1,6 +1,6 @@
{ {
"name": "@k8slens/generate-tray-icons", "name": "@k8slens/generate-tray-icons",
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"description": "CLI generating tray icons for building a lens-like application", "description": "CLI generating tray icons for building a lens-like application",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {

View File

@ -1,7 +1,7 @@
{ {
"name": "@k8slens/jest", "name": "@k8slens/jest",
"private": false, "private": false,
"version": "0.0.1", "version": "6.5.0-alpha.0",
"description": "Jest configuration and scripts for Lens packages.", "description": "Jest configuration and scripts for Lens packages.",
"type": "commonjs", "type": "commonjs",
"publishConfig": { "publishConfig": {

View File

@ -1,7 +1,7 @@
{ {
"name": "@k8slens/typescript", "name": "@k8slens/typescript",
"private": false, "private": false,
"version": "0.0.1", "version": "6.5.0-alpha.0",
"description": "Typescript configuration for Lens packages.", "description": "Typescript configuration for Lens packages.",
"type": "commonjs", "type": "commonjs",
"publishConfig": { "publishConfig": {

View File

@ -1,7 +1,7 @@
{ {
"name": "@k8slens/webpack", "name": "@k8slens/webpack",
"private": false, "private": false,
"version": "0.0.1", "version": "6.5.0-alpha.0",
"description": "Webpack configurations and scripts for Lens packages.", "description": "Webpack configurations and scripts for Lens packages.",
"type": "commonjs", "type": "commonjs",
"publishConfig": { "publishConfig": {
@ -25,6 +25,7 @@
"dependencies": { "dependencies": {
"@types/webpack-env": "^1.18.0", "@types/webpack-env": "^1.18.0",
"css-loader": "^6.7.2", "css-loader": "^6.7.2",
"fork-ts-checker-webpack-plugin": "^7.3.0",
"mini-css-extract-plugin": "^2.7.0", "mini-css-extract-plugin": "^2.7.0",
"sass-loader": "^13.2.0", "sass-loader": "^13.2.0",
"style-loader": "^3.3.1", "style-loader": "^3.3.1",

View File

@ -0,0 +1,226 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`get-multi-export-config given maximal package.json, when creating configuration works 1`] = `
Array [
Object {
"entry": Object {
"index": "./index.ts",
},
"externals": Array [
[Function],
[Function],
],
"externalsPresets": Object {
"node": true,
},
"mode": "production",
"module": Object {
"rules": Array [
Object {
"loader": "ts-loader",
"test": /\\\\\\.ts\\(x\\)\\?\\$/,
},
],
},
"name": "./index.ts",
"node": Object {
"__dirname": true,
"__filename": true,
},
"output": Object {
"filename": [Function],
"libraryTarget": "commonjs2",
"path": "/some-working-directory/dist",
},
"performance": Object {
"hints": "error",
"maxEntrypointSize": 100000,
},
"plugins": Array [
ForkTsCheckerWebpackPlugin {
"options": Object {
"typescript": Object {
"configOverwrite": Object {
"compilerOptions": Object {
"declaration": true,
"declarationDir": "/some-working-directory/dist",
},
"include": Array [
"./index.ts",
],
},
"mode": "write-dts",
},
},
},
],
"resolve": Object {
"extensions": Array [
".ts",
".tsx",
],
},
"target": "node",
},
Object {
"entry": Object {
"index": "./some-entrypoint/index.ts",
},
"externals": Array [
[Function],
[Function],
],
"externalsPresets": Object {
"node": true,
},
"mode": "production",
"module": Object {
"rules": Array [
Object {
"loader": "ts-loader",
"test": /\\\\\\.ts\\(x\\)\\?\\$/,
},
],
},
"name": "./some-entrypoint/index.ts",
"node": Object {
"__dirname": true,
"__filename": true,
},
"output": Object {
"filename": [Function],
"libraryTarget": "commonjs2",
"path": "/some-working-directory/dist/some-entrypoint",
},
"performance": Object {
"hints": "error",
"maxEntrypointSize": 100000,
},
"plugins": Array [
ForkTsCheckerWebpackPlugin {
"options": Object {
"typescript": Object {
"configOverwrite": Object {
"compilerOptions": Object {
"declaration": true,
"declarationDir": "/some-working-directory/dist/some-entrypoint",
},
"include": Array [
"./some-entrypoint/index.ts",
],
},
"mode": "write-dts",
},
},
},
],
"resolve": Object {
"extensions": Array [
".ts",
".tsx",
],
},
"target": "node",
},
Object {
"entry": Object {
"index": "./some-other-entrypoint/index.ts",
},
"externals": Array [
[Function],
[Function],
],
"externalsPresets": Object {
"node": true,
},
"mode": "production",
"module": Object {
"rules": Array [
Object {
"loader": "ts-loader",
"test": /\\\\\\.ts\\(x\\)\\?\\$/,
},
Object {
"test": /\\\\\\.s\\?css\\$/,
"use": Array [
Object {
"some": "miniCssExtractPluginLoader",
},
Object {
"loader": "css-loader",
"options": Object {
"modules": Object {
"auto": /\\\\\\.module\\\\\\./i,
"localIdentName": "[name]__[local]--[hash:base64:5]",
"mode": "local",
},
"sourceMap": false,
},
},
Object {
"loader": "sass-loader",
"options": Object {
"sourceMap": false,
},
},
],
},
],
},
"name": "./some-other-entrypoint/index.ts",
"node": Object {
"__dirname": true,
"__filename": true,
},
"output": Object {
"filename": [Function],
"libraryTarget": "commonjs2",
"path": "/some-working-directory/dist/some-other-entrypoint",
},
"performance": Object {
"hints": "error",
"maxEntrypointSize": 100000,
},
"plugins": Array [
ForkTsCheckerWebpackPlugin {
"options": Object {
"typescript": Object {
"configOverwrite": Object {
"compilerOptions": Object {
"declaration": true,
"declarationDir": "/some-working-directory/dist/some-other-entrypoint",
},
"include": Array [
"./some-other-entrypoint/index.ts",
],
},
"mode": "write-dts",
},
},
},
MiniCssExtractPlugin {
"_sortedModulesCache": WeakMap {},
"options": Object {
"chunkFilename": "[name].css",
"experimentalUseImportModule": undefined,
"filename": "[name].css",
"ignoreOrder": false,
"runtime": true,
},
"runtimeOptions": Object {
"attributes": undefined,
"insert": undefined,
"linkType": "text/css",
},
},
],
"resolve": Object {
"extensions": Array [
".ts",
".tsx",
],
},
"target": "node",
},
]
`;

View File

@ -1,5 +1,5 @@
const nodeConfig = require("./node-config"); const getNodeConfig = require("./get-node-config");
const reactConfig = require("./react-config"); const getReactConfigFor = require("./get-react-config");
const path = require("path"); const path = require("path");
const { const {
map, map,
@ -14,7 +14,15 @@ const {
} = require("lodash/fp"); } = require("lodash/fp");
const { pipeline } = require("@ogre-tools/fp"); const { pipeline } = require("@ogre-tools/fp");
module.exports = (packageJson, dependencies = { nodeConfig, reactConfig, joinPath: path.join }) => { module.exports = (
packageJson,
dependencies = {
resolvePath: path.resolve,
workingDirectory: process.cwd(),
getReactConfig: getReactConfigFor()
}
) => {
if (!packageJson.lensMultiExportConfig) { if (!packageJson.lensMultiExportConfig) {
throw new Error( throw new Error(
`Tried to get multi export config for package "${packageJson.name}" but configuration is missing.` `Tried to get multi export config for package "${packageJson.name}" but configuration is missing.`
@ -72,10 +80,13 @@ module.exports = (packageJson, dependencies = { nodeConfig, reactConfig, joinPat
); );
} }
const toExportSpecificWebpackConfig =
toExportSpecificWebpackConfigFor(dependencies);
return pipeline( return pipeline(
packageJson.lensMultiExportConfig, packageJson.lensMultiExportConfig,
toPairs, toPairs,
map(toExportSpecificWebpackConfigFor(dependencies)) map(toExportSpecificWebpackConfig)
); );
}; };
@ -91,7 +102,11 @@ const toExpectedExport = (externalImportPath) => {
return [ return [
externalImportPath, externalImportPath,
{ {
types: `./${posixJoinForPackageJson("./dist", externalImportPath, "index.d.ts")}`, types: `./${posixJoinForPackageJson(
"./dist",
externalImportPath,
"index.d.ts"
)}`,
default: entrypointPath, default: entrypointPath,
import: entrypointPath, import: entrypointPath,
@ -103,20 +118,19 @@ const toExpectedExport = (externalImportPath) => {
const toExportSpecificWebpackConfigFor = const toExportSpecificWebpackConfigFor =
(dependencies) => (dependencies) =>
([externalImportPath, { buildType, entrypoint }]) => { ([externalImportPath, { buildType, entrypoint }]) => {
const baseConfig = const outputDirectory = dependencies.resolvePath(
buildType === "node" ? dependencies.nodeConfig : dependencies.reactConfig; dependencies.workingDirectory,
"dist",
externalImportPath
);
return { return buildType === "node"
...baseConfig, ? getNodeConfig({
name: entrypoint, entrypointFilePath: entrypoint,
outputDirectory,
entry: { })
index: entrypoint, : dependencies.getReactConfig({
}, entrypointFilePath: entrypoint,
outputDirectory,
output: { });
...baseConfig.output,
path: dependencies.joinPath(baseConfig.output.path, externalImportPath),
},
};
}; };

View File

@ -1,10 +1,12 @@
import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin";
import getMultiExportConfig from "./get-multi-export-config"; import getMultiExportConfig from "./get-multi-export-config";
import path from 'path'; import path from "path";
const getReactConfigFor = require("./get-react-config");
const joinPathFake = path.posix.join; const resolvePathFake = path.posix.resolve;
describe("get-multi-export-config", () => { describe("get-multi-export-config", () => {
let actual; let configs;
let maximalPackageJson; let maximalPackageJson;
beforeEach(() => { beforeEach(() => {
@ -51,43 +53,69 @@ describe("get-multi-export-config", () => {
}; };
}); });
it("given maximal package.json, when creating configuration, works", () => { describe("given maximal package.json, when creating configuration", () => {
actual = getMultiExportConfig(maximalPackageJson, { beforeEach(() => {
nodeConfig: nodeConfigStub, configs = getMultiExportConfig(maximalPackageJson, {
reactConfig: reactConfigStub, resolvePath: resolvePathFake,
joinPath: joinPathFake, workingDirectory: "/some-working-directory",
getReactConfig: getReactConfigFor({
miniCssExtractPluginLoader: { some: "miniCssExtractPluginLoader" },
}),
});
}); });
expect(actual).toEqual([ it("works", () => {
expect(configs).toMatchSnapshot();
});
[
{ {
name: "./index.ts", name: "config for node export in default entrypoint",
stub: "node", entrypoint: "./index.ts",
entry: { index: "./index.ts" }, outputDirectory: "/some-working-directory/dist",
output: { some: "value", path: "/some-build-directory" },
}, },
{ {
name: "./some-entrypoint/index.ts", name: "config for node export in a non-default entrypoint",
stub: "node", entrypoint: "./some-entrypoint/index.ts",
entry: { index: "./some-entrypoint/index.ts" }, outputDirectory: "/some-working-directory/dist/some-entrypoint",
output: {
some: "value",
path: "/some-build-directory/some-entrypoint",
}, },
},
{ {
name: "./some-other-entrypoint/index.ts", name: "config for react export in a non-default entrypoint",
stub: "react", entrypoint: "./some-other-entrypoint/index.ts",
entry: { index: "./some-other-entrypoint/index.ts" }, outputDirectory: "/some-working-directory/dist/some-other-entrypoint",
},
].forEach((scenario) => {
describe(scenario.name, () => {
let config;
output: { beforeEach(() => {
some: "other-value", config = configs.find(({ name }) => name === scenario.entrypoint);
path: "/some-build-directory/some-other-entrypoint", });
},
}, it("has correct entrypoint", () => {
]); expect(config).toHaveProperty("entry.index", scenario.entrypoint);
});
it("has correct output directory", () => {
expect(config).toHaveProperty(
"output.path",
scenario.outputDirectory
);
});
it("has correct declaration directory", () => {
expect(
config.plugins.find(
({ constructor }) => constructor === ForkTsCheckerPlugin
)
).toHaveProperty(
"options.typescript.configOverwrite.compilerOptions.declarationDir",
scenario.outputDirectory
);
});
});
});
}); });
it("given maximal package.json but path for entrypoint in exports do not match output, when creating configuration, throws", () => { it("given maximal package.json but path for entrypoint in exports do not match output, when creating configuration, throws", () => {
@ -95,9 +123,9 @@ describe("get-multi-export-config", () => {
expect(() => { expect(() => {
getMultiExportConfig(maximalPackageJson, { getMultiExportConfig(maximalPackageJson, {
nodeConfig: nodeConfigStub, getNodeConfig: () => nodeConfigStub,
reactConfig: reactConfigStub, getReactConfig: () => reactConfigStub,
joinPath: joinPathFake, joinPath: resolvePathFake,
}); });
}).toThrow( }).toThrow(
'Tried to get multi export config but exports of package.json for "some-name" did not match exactly:' 'Tried to get multi export config but exports of package.json for "some-name" did not match exactly:'
@ -109,9 +137,9 @@ describe("get-multi-export-config", () => {
expect(() => { expect(() => {
getMultiExportConfig(maximalPackageJson, { getMultiExportConfig(maximalPackageJson, {
nodeConfig: nodeConfigStub, getNodeConfig: () => nodeConfigStub,
reactConfig: reactConfigStub, getReactConfig: () => reactConfigStub,
joinPath: joinPathFake, joinPath: resolvePathFake,
}); });
}).toThrow( }).toThrow(
'Tried to get multi export config but exports of package.json for "some-name" did not match exactly:' 'Tried to get multi export config but exports of package.json for "some-name" did not match exactly:'
@ -123,9 +151,9 @@ describe("get-multi-export-config", () => {
expect(() => { expect(() => {
getMultiExportConfig(maximalPackageJson, { getMultiExportConfig(maximalPackageJson, {
nodeConfig: nodeConfigStub, getNodeConfig: () => nodeConfigStub,
reactConfig: reactConfigStub, getReactConfig: () => reactConfigStub,
joinPath: joinPathFake, joinPath: resolvePathFake,
}); });
}).toThrow( }).toThrow(
'Tried to get multi export config but exports of package.json for "some-name" did not match exactly:' 'Tried to get multi export config but exports of package.json for "some-name" did not match exactly:'
@ -137,9 +165,9 @@ describe("get-multi-export-config", () => {
expect(() => { expect(() => {
getMultiExportConfig(maximalPackageJson, { getMultiExportConfig(maximalPackageJson, {
nodeConfig: nodeConfigStub, getNodeConfig: () => nodeConfigStub,
reactConfig: reactConfigStub, getReactConfig: () => reactConfigStub,
joinPath: joinPathFake, joinPath: resolvePathFake,
}); });
}).toThrow( }).toThrow(
'Tried to get multi export config for package "some-name" but configuration is missing.' 'Tried to get multi export config for package "some-name" but configuration is missing.'
@ -151,9 +179,9 @@ describe("get-multi-export-config", () => {
expect(() => { expect(() => {
getMultiExportConfig(maximalPackageJson, { getMultiExportConfig(maximalPackageJson, {
nodeConfig: nodeConfigStub, getNodeConfig: () => nodeConfigStub,
reactConfig: reactConfigStub, getReactConfig: () => reactConfigStub,
joinPath: joinPathFake, joinPath: resolvePathFake,
}); });
}).toThrow( }).toThrow(
'Tried to get multi export config for package "some-name" but build types "some-invalid" were not any of "node", "react".' 'Tried to get multi export config for package "some-name" but build types "some-invalid" were not any of "node", "react".'
@ -166,9 +194,9 @@ describe("get-multi-export-config", () => {
expect(() => { expect(() => {
getMultiExportConfig(maximalPackageJson, { getMultiExportConfig(maximalPackageJson, {
nodeConfig: nodeConfigStub, getNodeConfig: () => nodeConfigStub,
reactConfig: reactConfigStub, getReactConfig: () => reactConfigStub,
joinPath: joinPathFake, joinPath: resolvePathFake,
}); });
}).toThrow( }).toThrow(
'Tried to get multi export config for package "some-name" but entrypoint was missing for "./some-entrypoint".' 'Tried to get multi export config for package "some-name" but entrypoint was missing for "./some-entrypoint".'

View File

@ -0,0 +1,78 @@
const ForkTsCheckerPlugin = require("fork-ts-checker-webpack-plugin");
const nodeExternals = require("webpack-node-externals");
const path = require("path");
module.exports = ({ entrypointFilePath, outputDirectory }) => ({
name: entrypointFilePath,
entry: { index: entrypointFilePath },
target: "node",
mode: "production",
performance: {
maxEntrypointSize: 100000,
hints: "error",
},
resolve: {
extensions: [".ts", ".tsx"],
},
plugins: [
new ForkTsCheckerPlugin({
typescript: {
mode: "write-dts",
configOverwrite: {
include: [entrypointFilePath],
compilerOptions: {
declaration: true,
declarationDir: outputDirectory,
},
},
},
}),
],
output: {
path: outputDirectory,
filename: (pathData) =>
pathData.chunk.name === "index"
? "index.js"
: `${pathData.chunk.name}/index.js`,
libraryTarget: "commonjs2",
},
externals: [
nodeExternals({ modulesFromFile: true }),
nodeExternals({
modulesDir: path.resolve(
__dirname,
"..",
"..",
"..",
"..",
"node_modules"
),
}),
],
externalsPresets: { node: true },
node: {
__dirname: true,
__filename: true,
},
module: {
rules: [
{
test: /\.ts(x)?$/,
loader: "ts-loader",
},
],
},
});

View File

@ -0,0 +1,60 @@
const getNodeConfig = require("./get-node-config");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports =
({ miniCssExtractPluginLoader = MiniCssExtractPlugin.loader } = {}) =>
({ entrypointFilePath, outputDirectory }) => {
const nodeConfig = getNodeConfig({
entrypointFilePath,
outputDirectory,
});
return {
...nodeConfig,
plugins: [
...nodeConfig.plugins,
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
...nodeConfig.module,
rules: [
...nodeConfig.module.rules,
{
test: /\.s?css$/,
use: [
miniCssExtractPluginLoader,
{
loader: "css-loader",
options: {
sourceMap: false,
modules: {
auto: /\.module\./i, // https://github.com/webpack-contrib/css-loader#auto
mode: "local", // :local(.selector) by default
localIdentName: "[name]__[local]--[hash:base64:5]",
},
},
},
{
loader: "sass-loader",
options: {
sourceMap: false,
},
},
],
},
],
},
};
};

View File

@ -1,68 +1,7 @@
const nodeExternals = require("webpack-node-externals");
const path = require("path"); const path = require("path");
const getNodeConfig = require("./get-node-config");
const buildDirectory = path.resolve(process.cwd(), "dist"); module.exports = getNodeConfig({
entrypointFilePath: "./index.ts",
module.exports = { outputDirectory: path.resolve(process.cwd(), "dist"),
entry: { index: "./index.ts" }, });
target: "node",
mode: "production",
performance: {
maxEntrypointSize: 100000,
hints: "error",
},
resolve: {
extensions: [".ts", ".tsx"],
},
output: {
path: buildDirectory,
filename: (pathData) =>
pathData.chunk.name === "index"
? "index.js"
: `${pathData.chunk.name}/index.js`,
libraryTarget: "commonjs2",
},
externals: [
nodeExternals({ modulesFromFile: true }),
nodeExternals({
modulesDir: path.resolve(
__dirname,
"..",
"..",
"..",
"..",
"node_modules"
),
}),
],
externalsPresets: { node: true },
node: {
__dirname: true,
__filename: true,
},
module: {
rules: [
{
test: /\.ts(x)?$/,
loader: "ts-loader",
options: {
compilerOptions: {
declaration: true,
declarationDir: "./dist",
},
},
},
],
},
};

View File

@ -1,44 +1,7 @@
const nodeConfig = require("./node-config"); const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const getReactConfig = require("./get-react-config");
module.exports = { module.exports = getReactConfig({
...nodeConfig, entrypointFilePath: "./index.ts",
outputDirectory: path.resolve(process.cwd(), "dist"),
plugins: [ });
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
module: {
...nodeConfig.module,
rules: [
...nodeConfig.module.rules,
{
test: /\.s?css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: false,
modules: {
auto: /\.module\./i, // https://github.com/webpack-contrib/css-loader#auto
mode: "local", // :local(.selector) by default
localIdentName: "[name]__[local]--[hash:base64:5]",
},
},
},
{
loader: "sass-loader",
options: {
sourceMap: false,
},
},
],
},
],
},
};

View File

@ -1,6 +1,6 @@
{ {
"name": "@k8slens/node-fetch", "name": "@k8slens/node-fetch",
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"description": "Node fetch for Lens", "description": "Node fetch for Lens",
"license": "MIT", "license": "MIT",
"private": false, "private": false,

View File

@ -4,7 +4,7 @@
"productName": "OpenLens", "productName": "OpenLens",
"description": "OpenLens - Open Source IDE for Kubernetes", "description": "OpenLens - Open Source IDE for Kubernetes",
"homepage": "https://github.com/lensapp/lens", "homepage": "https://github.com/lensapp/lens",
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/lensapp/lens.git" "url": "git+https://github.com/lensapp/lens.git"
@ -195,10 +195,10 @@
} }
}, },
"dependencies": { "dependencies": {
"@k8slens/application": "^6.4.0-beta.13", "@k8slens/application": "^6.5.0-alpha.0",
"@k8slens/core": "^6.4.0-beta.13", "@k8slens/core": "^6.5.0-alpha.0",
"@k8slens/ensure-binaries": "^6.4.0-beta.13", "@k8slens/ensure-binaries": "^6.5.0-alpha.0",
"@k8slens/generate-tray-icons": "^6.4.0-beta.13", "@k8slens/generate-tray-icons": "^6.5.0-alpha.0",
"@ogre-tools/fp": "^15.1.1", "@ogre-tools/fp": "^15.1.1",
"@ogre-tools/injectable": "^15.1.1", "@ogre-tools/injectable": "^15.1.1",
"@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1", "@ogre-tools/injectable-extension-for-auto-registration": "^15.1.1",
@ -208,7 +208,8 @@
"rimraf": "^4.1.2" "rimraf": "^4.1.2"
}, },
"devDependencies": { "devDependencies": {
"@k8slens/node-fetch": "^6.4.0-beta.13", "@electron/rebuild": "^3.2.10",
"@k8slens/node-fetch": "^6.5.0-alpha.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
"@swc/cli": "^0.1.61", "@swc/cli": "^0.1.61",
"@swc/core": "^1.3.35", "@swc/core": "^1.3.35",
@ -272,7 +273,6 @@
"webpack-cli": "^4.9.2", "webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.11.1", "webpack-dev-server": "^4.11.1",
"webpack-node-externals": "^3.0.0", "webpack-node-externals": "^3.0.0",
"xterm-addon-fit": "^0.5.0", "xterm-addon-fit": "^0.5.0"
"@electron/rebuild": "^3.2.10"
} }
} }

View File

@ -8,12 +8,9 @@ import { applicationInformationToken } from "@k8slens/application";
const applicationInformationInjectable = getInjectable({ const applicationInformationInjectable = getInjectable({
id: "application-information", id: "application-information",
injectionToken: applicationInformationToken,
instantiate: () => { instantiate: () => {
const { const {
version, version,
config: { config: {
bundledHelmVersion, bundledHelmVersion,
bundledKubectlVersion, bundledKubectlVersion,
@ -22,12 +19,12 @@ const applicationInformationInjectable = getInjectable({
sentryDsn, sentryDsn,
welcomeRoute, welcomeRoute,
}, },
productName, productName,
build, build,
copyright, copyright,
description, description,
name, name,
dependencies,
} = packageJson; } = packageJson;
return { return {
@ -43,9 +40,11 @@ const applicationInformationInjectable = getInjectable({
contentSecurityPolicy, contentSecurityPolicy,
welcomeRoute, welcomeRoute,
updatingIsEnabled: (build as any)?.publish?.length > 0, updatingIsEnabled: (build as any)?.publish?.length > 0,
dependencies,
}; };
}, },
causesSideEffects: true, causesSideEffects: true,
injectionToken: applicationInformationToken,
}); });
export default applicationInformationInjectable; export default applicationInformationInjectable;

View File

@ -1,18 +1,15 @@
import { createContainer } 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 { runInAction } from "mobx"; import { runInAction } from "mobx";
import { createApp, mainExtensionApi as Main, commonExtensionApi as Common } from "@k8slens/core/main"; import { createApplication, mainExtensionApi as Main, commonExtensionApi as Common } from "@k8slens/core/main";
const di = createContainer("main"); const app = createApplication({
const app = createApp({
di,
mode: process.env.NODE_ENV || "development" mode: process.env.NODE_ENV || "development"
}); });
runInAction(() => { runInAction(() => {
try { try {
autoRegister({ autoRegister({
di, di: app.di,
targetModule: module, targetModule: module,
getRequireContexts: () => [ getRequireContexts: () => [
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES), require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),

View File

@ -1,18 +1,15 @@
import "@k8slens/core/styles"; import "@k8slens/core/styles";
import { createContainer } from "@ogre-tools/injectable";
import { runInAction } from "mobx"; import { runInAction } from "mobx";
import { createApp, rendererExtensionApi as Renderer, commonExtensionApi as Common } from "@k8slens/core/renderer"; import { createApplication, rendererExtensionApi as Renderer, commonExtensionApi as Common } from "@k8slens/core/renderer";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration"; import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
const di = createContainer("renderer"); const app = createApplication({
const app = createApp({
di,
mode: process.env.NODE_ENV || "development" mode: process.env.NODE_ENV || "development"
}); });
runInAction(() => { runInAction(() => {
autoRegister({ autoRegister({
di, di: app.di,
targetModule: module, targetModule: module,
getRequireContexts: () => [ getRequireContexts: () => [
require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES), require.context("./", true, CONTEXT_MATCHER_FOR_NON_FEATURES),

View File

@ -1,6 +1,6 @@
{ {
"name": "@k8slens/release-tool", "name": "@k8slens/release-tool",
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"description": "Release tool for lens monorepo", "description": "Release tool for lens monorepo",
"main": "dist/index.mjs", "main": "dist/index.mjs",
"license": "MIT", "license": "MIT",

View File

@ -1,6 +1,6 @@
{ {
"name": "@k8slens/semver", "name": "@k8slens/semver",
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"description": "CLI over semver package for picking parts of a version", "description": "CLI over semver package for picking parts of a version",
"license": "MIT", "license": "MIT",
"private": true, "private": true,

View File

@ -1,7 +1,7 @@
{ {
"name": "@k8slens/application", "name": "@k8slens/application",
"private": false, "private": false,
"version": "6.4.0-beta.13", "version": "6.5.0-alpha.0",
"description": "Package for creating Lens applications", "description": "Package for creating Lens applications",
"type": "commonjs", "type": "commonjs",
"files": [ "files": [

View File

@ -17,6 +17,7 @@ export type ApplicationInformation = {
contentSecurityPolicy: string, contentSecurityPolicy: string,
welcomeRoute: string, welcomeRoute: string,
updatingIsEnabled: boolean; updatingIsEnabled: boolean;
dependencies: Partial<Record<string, string>>;
} }
export const applicationInformationToken = getInjectionToken<ApplicationInformation>({ export const applicationInformationToken = getInjectionToken<ApplicationInformation>({

View File

@ -1,9 +1,15 @@
{ {
"name": "@k8slens/feature-core", "name": "@k8slens/feature-core",
"private": false, "private": false,
"version": "0.0.1", "version": "6.5.0-alpha.0",
"description": "Code that is common to all Features and those registering them.", "description": "Code that is common to all Features and those registering them.",
"type": "commonjs", "type": "commonjs",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"files": [ "files": [
"dist" "dist"
], ],