From c1e88a8a3b74c9736230031129b8f1147b35173d Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 15 Mar 2023 10:11:48 -0400 Subject: [PATCH 1/3] Fix bundled extensions not being loaded - Also show that this fixes it by added an example bundled extension to 'open-lens' Signed-off-by: Sebastian Malton --- package-lock.json | 158 ++++++++++++++++++ packages/core/package.json | 5 +- packages/core/src/common/library.ts | 7 - .../__tests__/is-compatible-extension.test.ts | 2 +- .../core/src/extensions/common-api/index.ts | 4 +- .../bundled-extension-token.ts | 17 -- .../extension-discovery.ts | 18 +- .../is-compatible-extension.ts | 2 +- .../create-extension-instance.token.ts | 4 +- .../extension-instances.injectable.ts | 3 +- .../extension-loader.injectable.ts | 2 +- .../extension-loader/extension-loader.ts | 5 +- .../file-system-provisioner-store.ts | 2 +- .../registered-extensions.injectable.ts | 2 +- .../extensions-store/extensions-store.ts | 2 +- .../core/src/extensions/lens-extension.ts | 27 +-- .../about-bundled-extensions.injectable.ts | 2 +- .../protocol-handler/__test__/router.test.ts | 2 +- .../initialize-extensions.injectable.ts | 6 +- .../attempt-install.injectable.tsx | 2 +- ...ate-temp-files-and-validate.injectable.tsx | 2 +- .../attempt-install/validate-package.tsx | 2 +- ...confirm-uninstall-extension.injectable.tsx | 3 +- .../disable-extension/disable-extension.ts | 2 +- .../enable-extension/enable-extension.ts | 2 +- .../components/+extensions/extensions.tsx | 6 +- .../+extensions/installed-extensions.tsx | 14 +- .../uninstall-extension.injectable.tsx | 2 +- packages/core/src/renderer/ipc/index.ts | 3 +- packages/core/webpack/common.ts | 37 ---- packages/core/webpack/library-bundle.ts | 2 - .../legacy-extension-example/.eslintrc.json | 6 + .../legacy-extension-example/jest.config.js | 1 + packages/legacy-extension-example/main.ts | 3 + .../legacy-extension-example/package.json | 46 +++++ .../legacy-extension-example/renderer.tsx | 11 ++ .../legacy-extension-example/tsconfig.json | 4 + packages/legacy-extension-example/webpack.ts | 85 ++++++++++ packages/open-lens/package.json | 2 + .../example-bundled-extension.injectable.ts | 15 ++ .../application/agnostic/.eslintrc.js | 6 - .../application/agnostic/.eslintrc.json | 6 + .../legacy-extensions/.eslintrc.json | 6 + .../application/legacy-extensions/README.md | 5 + .../application/legacy-extensions/index.ts | 2 + .../legacy-extensions/jest.config.js | 1 + .../legacy-extensions/package.json | 39 +++++ .../src/bundled-extension.ts | 16 ++ .../legacy-extensions/src/lens-extension.ts | 63 +++++++ .../legacy-extensions/tsconfig.json | 4 + .../legacy-extensions/webpack.config.js | 1 + 51 files changed, 510 insertions(+), 159 deletions(-) delete mode 100644 packages/core/src/common/library.ts delete mode 100644 packages/core/src/extensions/extension-discovery/bundled-extension-token.ts delete mode 100644 packages/core/webpack/common.ts create mode 100644 packages/legacy-extension-example/.eslintrc.json create mode 100644 packages/legacy-extension-example/jest.config.js create mode 100644 packages/legacy-extension-example/main.ts create mode 100644 packages/legacy-extension-example/package.json create mode 100644 packages/legacy-extension-example/renderer.tsx create mode 100644 packages/legacy-extension-example/tsconfig.json create mode 100644 packages/legacy-extension-example/webpack.ts create mode 100644 packages/open-lens/src/common/example-bundled-extension.injectable.ts delete mode 100644 packages/technical-features/application/agnostic/.eslintrc.js create mode 100644 packages/technical-features/application/agnostic/.eslintrc.json create mode 100644 packages/technical-features/application/legacy-extensions/.eslintrc.json create mode 100644 packages/technical-features/application/legacy-extensions/README.md create mode 100644 packages/technical-features/application/legacy-extensions/index.ts create mode 100644 packages/technical-features/application/legacy-extensions/jest.config.js create mode 100644 packages/technical-features/application/legacy-extensions/package.json create mode 100644 packages/technical-features/application/legacy-extensions/src/bundled-extension.ts create mode 100644 packages/technical-features/application/legacy-extensions/src/lens-extension.ts create mode 100644 packages/technical-features/application/legacy-extensions/tsconfig.json create mode 100644 packages/technical-features/application/legacy-extensions/webpack.config.js diff --git a/package-lock.json b/package-lock.json index 61ba8e5f3b55..c60e095894d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4714,6 +4714,14 @@ "resolved": "packages/infrastructure/jest", "link": true }, + "node_modules/@k8slens/legacy-extension-example": { + "resolved": "packages/legacy-extension-example", + "link": true + }, + "node_modules/@k8slens/legacy-extensions": { + "resolved": "packages/technical-features/application/legacy-extensions", + "link": true + }, "node_modules/@k8slens/node-fetch": { "resolved": "packages/node-fetch", "link": true @@ -34589,6 +34597,7 @@ "peerDependencies": { "@k8slens/application": "^6.5.0-alpha.0", "@k8slens/application-for-electron-main": "^6.5.0-alpha.0", + "@k8slens/legacy-extensions": "^1.0.0-alpha.0", "@k8slens/run-many": "^1.0.0-alpha.1", "@k8slens/test-utils": "^1.0.0-alpha.1", "@k8slens/utilities": "^1.0.0-alpha.1", @@ -36366,6 +36375,142 @@ } } }, + "packages/legacy-extension-example": { + "name": "@k8slens/legacy-extension-example", + "version": "1.0.0-alpha.0", + "license": "MIT", + "devDependencies": { + "@types/node": "^16.18.16", + "typescript": "^4.9.5", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1" + } + }, + "packages/legacy-extension-example/node_modules/@types/node": { + "version": "16.18.16", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.16.tgz", + "integrity": "sha512-ZOzvDRWp8dCVBmgnkIqYCArgdFOO9YzocZp8Ra25N/RStKiWvMOXHMz+GjSeVNe5TstaTmTWPucGJkDw0XXJWA==", + "dev": true + }, + "packages/legacy-extension-example/node_modules/@webpack-cli/configtest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz", + "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "packages/legacy-extension-example/node_modules/@webpack-cli/info": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", + "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "packages/legacy-extension-example/node_modules/@webpack-cli/serve": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz", + "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "packages/legacy-extension-example/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "packages/legacy-extension-example/node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "packages/legacy-extension-example/node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "packages/legacy-extension-example/node_modules/webpack-cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz", + "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.0.1", + "@webpack-cli/info": "^2.0.1", + "@webpack-cli/serve": "^2.0.1", + "colorette": "^2.0.14", + "commander": "^9.4.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, "packages/node-fetch": { "name": "@k8slens/node-fetch", "version": "6.5.0-alpha.1", @@ -36513,6 +36658,8 @@ "@k8slens/ensure-binaries": "^6.5.0-alpha.1", "@k8slens/feature-core": "^6.5.0-alpha.1", "@k8slens/generate-tray-icons": "^6.5.0-alpha.1", + "@k8slens/legacy-extension-example": "^1.0.0-alpha.0", + "@k8slens/legacy-extensions": "^1.0.0-alpha.0", "@k8slens/run-many": "^1.0.0-alpha.1", "@k8slens/test-utils": "^1.0.0-alpha.1", "@k8slens/utilities": "^1.0.0-alpha.1", @@ -37055,6 +37202,17 @@ "electron": "^19.1.9" } }, + "packages/technical-features/application/legacy-extensions": { + "name": "@k8slens/legacy-extensions", + "version": "1.0.0-alpha.0", + "license": "MIT", + "devDependencies": { + "@k8slens/eslint-config": "6.5.0-alpha.1" + }, + "peerDependencies": { + "@ogre-tools/injectable": "^15.1.2" + } + }, "packages/technical-features/feature-core": { "name": "@k8slens/feature-core", "version": "6.5.0-alpha.1", diff --git a/packages/core/package.json b/packages/core/package.json index 319830e9e5ce..c17010f80753 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -20,7 +20,6 @@ "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": { @@ -30,9 +29,6 @@ ], "renderer": [ "./static/build/library/src/renderer/library.d.ts" - ], - "common": [ - "./static/build/library/src/common/library.d.ts" ] } }, @@ -331,6 +327,7 @@ "peerDependencies": { "@k8slens/application": "^6.5.0-alpha.0", "@k8slens/application-for-electron-main": "^6.5.0-alpha.0", + "@k8slens/legacy-extensions": "^1.0.0-alpha.0", "@k8slens/run-many": "^1.0.0-alpha.1", "@k8slens/test-utils": "^1.0.0-alpha.1", "@k8slens/utilities": "^1.0.0-alpha.1", diff --git a/packages/core/src/common/library.ts b/packages/core/src/common/library.ts deleted file mode 100644 index bc625eb3dd4e..000000000000 --- a/packages/core/src/common/library.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -// @experimental -export { bundledExtensionInjectionToken } from "../extensions/extension-discovery/bundled-extension-token"; diff --git a/packages/core/src/extensions/__tests__/is-compatible-extension.test.ts b/packages/core/src/extensions/__tests__/is-compatible-extension.test.ts index f2ca144681e8..8aa16419bc1c 100644 --- a/packages/core/src/extensions/__tests__/is-compatible-extension.test.ts +++ b/packages/core/src/extensions/__tests__/is-compatible-extension.test.ts @@ -3,8 +3,8 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { LensExtensionManifest } from "@k8slens/legacy-extensions"; import { isCompatibleExtension } from "../extension-discovery/is-compatible-extension/is-compatible-extension"; -import type { LensExtensionManifest } from "../lens-extension"; describe("Extension/App versions compatibility checks", () => { it("is compatible with exact version matching", () => { diff --git a/packages/core/src/extensions/common-api/index.ts b/packages/core/src/extensions/common-api/index.ts index ddfaae5dd6e8..83b6ae28b66b 100644 --- a/packages/core/src/extensions/common-api/index.ts +++ b/packages/core/src/extensions/common-api/index.ts @@ -16,8 +16,8 @@ export * as Types from "./types"; export * as Proxy from "./proxy"; export type { Logger } from "../../common/logger"; -export type { LensExtension, LensExtensionManifest } from "../lens-extension"; -export type { InstalledExtension } from "../extension-discovery/extension-discovery"; +export type { LensExtension } from "../lens-extension"; export type { PackageJson } from "type-fest"; +export type { LensExtensionManifest, InstalledExtension } from "@k8slens/legacy-extensions"; export const logger = asLegacyGlobalForExtensionApi(loggerInjectable); diff --git a/packages/core/src/extensions/extension-discovery/bundled-extension-token.ts b/packages/core/src/extensions/extension-discovery/bundled-extension-token.ts deleted file mode 100644 index 1a1a40f9fae6..000000000000 --- a/packages/core/src/extensions/extension-discovery/bundled-extension-token.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import { getInjectionToken } from "@ogre-tools/injectable"; -import type { LensExtensionConstructor, LensExtensionManifest } from "../lens-extension"; - -export interface BundledExtension { - readonly manifest: LensExtensionManifest; - main: () => LensExtensionConstructor | null; - renderer: () => LensExtensionConstructor | null; -} - -export const bundledExtensionInjectionToken = getInjectionToken({ - id: "bundled-extension-path", -}); diff --git a/packages/core/src/extensions/extension-discovery/extension-discovery.ts b/packages/core/src/extensions/extension-discovery/extension-discovery.ts index a91bf9e40677..88864d86631f 100644 --- a/packages/core/src/extensions/extension-discovery/extension-discovery.ts +++ b/packages/core/src/extensions/extension-discovery/extension-discovery.ts @@ -11,7 +11,7 @@ import { toJS } from "../../common/utils"; import { isErrnoException } from "@k8slens/utilities"; import type { ExtensionsStore } from "../extensions-store/extensions-store"; import type { ExtensionLoader } from "../extension-loader"; -import type { LensExtensionId, LensExtensionManifest } from "../lens-extension"; +import type { InstalledExtension, LensExtensionId, LensExtensionManifest } from "@k8slens/legacy-extensions"; import type { ExtensionInstallationStateStore } from "../extension-installation-state-store/extension-installation-state-store"; import { extensionDiscoveryStateChannel } from "../../common/ipc/extension-handling"; import { requestInitialExtensionDiscovery } from "../../renderer/ipc"; @@ -59,22 +59,6 @@ interface Dependencies { getRelativePath: GetRelativePath; } -export interface InstalledExtension { - id: LensExtensionId; - - readonly manifest: LensExtensionManifest; - - // Absolute path to the non-symlinked source folder, - // e.g. "/Users/user/.k8slens/extensions/helloworld" - readonly absolutePath: string; - - // Absolute to the symlinked package.json file - readonly manifestPath: string; - readonly isBundled: boolean; // defined in project root's package.json - readonly isCompatible: boolean; - isEnabled: boolean; -} - const logModule = "[EXTENSION-DISCOVERY]"; export const manifestFilename = "package.json"; diff --git a/packages/core/src/extensions/extension-discovery/is-compatible-extension/is-compatible-extension.ts b/packages/core/src/extensions/extension-discovery/is-compatible-extension/is-compatible-extension.ts index 74cbb4fd0c00..9d121317a179 100644 --- a/packages/core/src/extensions/extension-discovery/is-compatible-extension/is-compatible-extension.ts +++ b/packages/core/src/extensions/extension-discovery/is-compatible-extension/is-compatible-extension.ts @@ -2,8 +2,8 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { LensExtensionManifest } from "@k8slens/legacy-extensions"; import semver from "semver"; -import type { LensExtensionManifest } from "../../lens-extension"; interface Dependencies { extensionApiVersion: string; diff --git a/packages/core/src/extensions/extension-loader/create-extension-instance.token.ts b/packages/core/src/extensions/extension-loader/create-extension-instance.token.ts index d7680b018b23..a064cf55ec15 100644 --- a/packages/core/src/extensions/extension-loader/create-extension-instance.token.ts +++ b/packages/core/src/extensions/extension-loader/create-extension-instance.token.ts @@ -3,9 +3,9 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { LensExtensionConstructor, InstalledExtension } from "@k8slens/legacy-extensions"; import { getInjectionToken } from "@ogre-tools/injectable"; -import type { InstalledExtension } from "../extension-discovery/extension-discovery"; -import type { LensExtension, LensExtensionConstructor } from "../lens-extension"; +import type { LensExtension } from "../lens-extension"; export type CreateExtensionInstance = (ExtensionClass: LensExtensionConstructor, extension: InstalledExtension) => LensExtension; diff --git a/packages/core/src/extensions/extension-loader/extension-instances.injectable.ts b/packages/core/src/extensions/extension-loader/extension-instances.injectable.ts index 08e7ad4cc522..fe95b858ebbd 100644 --- a/packages/core/src/extensions/extension-loader/extension-instances.injectable.ts +++ b/packages/core/src/extensions/extension-loader/extension-instances.injectable.ts @@ -2,9 +2,10 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { LensExtensionId } from "@k8slens/legacy-extensions"; import { getInjectable } from "@ogre-tools/injectable"; import { observable } from "mobx"; -import type { LensExtensionId, LensExtension } from "../lens-extension"; +import type { LensExtension } from "../lens-extension"; const extensionInstancesInjectable = getInjectable({ id: "extension-instances", diff --git a/packages/core/src/extensions/extension-loader/extension-loader.injectable.ts b/packages/core/src/extensions/extension-loader/extension-loader.injectable.ts index 67f843404310..e635a6cca1e4 100644 --- a/packages/core/src/extensions/extension-loader/extension-loader.injectable.ts +++ b/packages/core/src/extensions/extension-loader/extension-loader.injectable.ts @@ -12,7 +12,7 @@ import extensionInjectable from "./extension/extension.injectable"; import loggerInjectable from "../../common/logger.injectable"; import joinPathsInjectable from "../../common/path/join-paths.injectable"; import getDirnameOfPathInjectable from "../../common/path/get-dirname.injectable"; -import { bundledExtensionInjectionToken } from "../extension-discovery/bundled-extension-token"; +import { bundledExtensionInjectionToken } from "@k8slens/legacy-extensions"; import { extensionEntryPointNameInjectionToken } from "./entry-point-name"; const extensionLoaderInjectable = getInjectable({ diff --git a/packages/core/src/extensions/extension-loader/extension-loader.ts b/packages/core/src/extensions/extension-loader/extension-loader.ts index b82fe5c15961..7d41ec1fdafc 100644 --- a/packages/core/src/extensions/extension-loader/extension-loader.ts +++ b/packages/core/src/extensions/extension-loader/extension-loader.ts @@ -9,8 +9,7 @@ import type { ObservableMap } from "mobx"; import { action, computed, makeObservable, toJS, observable, observe, reaction, when } from "mobx"; import { broadcastMessage, ipcMainOn, ipcRendererOn, ipcMainHandle } from "../../common/ipc"; import { isDefined } from "@k8slens/utilities"; -import type { InstalledExtension } from "../extension-discovery/extension-discovery"; -import type { LensExtension, LensExtensionConstructor, LensExtensionId } from "../lens-extension"; +import type { LensExtension } from "../lens-extension"; import type { LensExtensionState } from "../extensions-store/extensions-store"; import { extensionLoaderFromMainChannel, extensionLoaderFromRendererChannel } from "../../common/ipc/extension-handling"; import { requestExtensionLoaderInitialState } from "../../renderer/ipc"; @@ -21,7 +20,7 @@ import type { Extension } from "./extension/extension.injectable"; import type { Logger } from "../../common/logger"; import type { JoinPaths } from "../../common/path/join-paths.injectable"; import type { GetDirnameOfPath } from "../../common/path/get-dirname.injectable"; -import type { BundledExtension } from "../extension-discovery/bundled-extension-token"; +import type { LensExtensionId, BundledExtension, InstalledExtension, LensExtensionConstructor } from "@k8slens/legacy-extensions"; const logModule = "[EXTENSIONS-LOADER]"; diff --git a/packages/core/src/extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.ts b/packages/core/src/extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.ts index 86d978d47c00..6c48210479e9 100644 --- a/packages/core/src/extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.ts +++ b/packages/core/src/extensions/extension-loader/file-system-provisioner-store/file-system-provisioner-store.ts @@ -3,11 +3,11 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { LensExtensionId } from "@k8slens/legacy-extensions"; import type { ObservableMap } from "mobx"; import { action, makeObservable } from "mobx"; import type { BaseStoreDependencies } from "../../../common/base-store/base-store"; import { BaseStore } from "../../../common/base-store/base-store"; -import type { LensExtensionId } from "../../lens-extension"; import type { EnsureHashedDirectoryForExtension } from "./ensure-hashed-directory-for-extension.injectable"; interface FSProvisionModel { diff --git a/packages/core/src/extensions/extension-loader/file-system-provisioner-store/registered-extensions.injectable.ts b/packages/core/src/extensions/extension-loader/file-system-provisioner-store/registered-extensions.injectable.ts index 93fb7a342ce0..b10dc51ecd60 100644 --- a/packages/core/src/extensions/extension-loader/file-system-provisioner-store/registered-extensions.injectable.ts +++ b/packages/core/src/extensions/extension-loader/file-system-provisioner-store/registered-extensions.injectable.ts @@ -2,9 +2,9 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { LensExtensionId } from "@k8slens/legacy-extensions"; import { getInjectable } from "@ogre-tools/injectable"; import { observable } from "mobx"; -import type { LensExtensionId } from "../../lens-extension"; export const registeredExtensionsInjectable = getInjectable({ id: "registered-extensions", diff --git a/packages/core/src/extensions/extensions-store/extensions-store.ts b/packages/core/src/extensions/extensions-store/extensions-store.ts index 1a8e5376b6c8..17766d26d79e 100644 --- a/packages/core/src/extensions/extensions-store/extensions-store.ts +++ b/packages/core/src/extensions/extensions-store/extensions-store.ts @@ -3,7 +3,7 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { LensExtensionId } from "../lens-extension"; +import type { LensExtensionId } from "@k8slens/legacy-extensions"; import { action, computed, makeObservable, observable } from "mobx"; import type { BaseStoreDependencies } from "../../common/base-store/base-store"; import { BaseStore } from "../../common/base-store/base-store"; diff --git a/packages/core/src/extensions/lens-extension.ts b/packages/core/src/extensions/lens-extension.ts index 30cf19e4a44d..83ba4ebaec89 100644 --- a/packages/core/src/extensions/lens-extension.ts +++ b/packages/core/src/extensions/lens-extension.ts @@ -3,35 +3,12 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { InstalledExtension } from "./extension-discovery/extension-discovery"; import { action, computed, makeObservable, observable } from "mobx"; -import type { PackageJson } from "type-fest"; import { disposer } from "@k8slens/utilities"; import type { LensExtensionDependencies } from "./lens-extension-set-dependencies"; import type { ProtocolHandlerRegistration } from "../common/protocol-handler/registration"; +import type { InstalledExtension, LegacyLensExtension, LensExtensionId, LensExtensionManifest } from "@k8slens/legacy-extensions"; -export type LensExtensionId = string; // path to manifest (package.json) -export type LensExtensionConstructor = new (...args: ConstructorParameters) => LensExtension; - -export interface LensExtensionManifest extends PackageJson { - name: string; - version: string; - main?: string; // path to %ext/dist/main.js - renderer?: string; // path to %ext/dist/renderer.js - /** - * Supported Lens version engine by extension could be defined in `manifest.engines.lens` - * Only MAJOR.MINOR version is taken in consideration. - */ - engines: { - lens: string; // "semver"-package format - npm?: string; - node?: string; - }; - - // Specify extension name used for persisting data. - // Useful if extension is renamed but the data should not be lost. - storeName?: string; -} export const lensExtensionDependencies = Symbol("lens-extension-dependencies"); export const Disposers = Symbol("disposers"); @@ -41,7 +18,7 @@ export class LensExtension< * @ignore */ Dependencies extends LensExtensionDependencies = LensExtensionDependencies, -> { +> implements LegacyLensExtension { readonly id: LensExtensionId; readonly manifest: LensExtensionManifest; readonly manifestPath: string; diff --git a/packages/core/src/features/application-menu/main/menu-items/special-menu-for-mac-application/show-about-application/about-bundled-extensions.injectable.ts b/packages/core/src/features/application-menu/main/menu-items/special-menu-for-mac-application/show-about-application/about-bundled-extensions.injectable.ts index 59ae1e149174..59787ebfa113 100644 --- a/packages/core/src/features/application-menu/main/menu-items/special-menu-for-mac-application/show-about-application/about-bundled-extensions.injectable.ts +++ b/packages/core/src/features/application-menu/main/menu-items/special-menu-for-mac-application/show-about-application/about-bundled-extensions.injectable.ts @@ -4,7 +4,7 @@ */ import { applicationInformationToken } from "@k8slens/application"; import { getInjectable } from "@ogre-tools/injectable"; -import { bundledExtensionInjectionToken } from "../../../../../../common/library"; +import { bundledExtensionInjectionToken } from "@k8slens/legacy-extensions"; import { object } from "@k8slens/utilities"; import buildSemanticVersionInjectable from "../../../../../../common/vars/build-semantic-version.injectable"; diff --git a/packages/core/src/main/protocol-handler/__test__/router.test.ts b/packages/core/src/main/protocol-handler/__test__/router.test.ts index 7919e3f5969e..5af2e588d8ef 100644 --- a/packages/core/src/main/protocol-handler/__test__/router.test.ts +++ b/packages/core/src/main/protocol-handler/__test__/router.test.ts @@ -14,7 +14,6 @@ import lensProtocolRouterMainInjectable from "../lens-protocol-router-main/lens- import extensionsStoreInjectable from "../../../extensions/extensions-store/extensions-store.injectable"; import getConfigurationFileModelInjectable from "../../../common/get-configuration-file-model/get-configuration-file-model.injectable"; import { LensExtension } from "../../../extensions/lens-extension"; -import type { LensExtensionId } from "../../../extensions/lens-extension"; import type { ObservableMap } from "mobx"; import extensionInstancesInjectable from "../../../extensions/extension-loader/extension-instances.injectable"; import directoryForUserDataInjectable from "../../../common/app-paths/directory-for-user-data/directory-for-user-data.injectable"; @@ -23,6 +22,7 @@ import pathExistsSyncInjectable from "../../../common/fs/path-exists-sync.inject import pathExistsInjectable from "../../../common/fs/path-exists.injectable"; import readJsonSyncInjectable from "../../../common/fs/read-json-sync.injectable"; import writeJsonSyncInjectable from "../../../common/fs/write-json-sync.injectable"; +import type { LensExtensionId } from "@k8slens/legacy-extensions"; function throwIfDefined(val: any): void { if (val != null) { diff --git a/packages/core/src/main/start-main-application/runnables/initialize-extensions.injectable.ts b/packages/core/src/main/start-main-application/runnables/initialize-extensions.injectable.ts index d9c1aed4737e..a986bea2ef94 100644 --- a/packages/core/src/main/start-main-application/runnables/initialize-extensions.injectable.ts +++ b/packages/core/src/main/start-main-application/runnables/initialize-extensions.injectable.ts @@ -3,8 +3,6 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ import { getInjectable } from "@ogre-tools/injectable"; -import type { InstalledExtension } from "../../../extensions/extension-discovery/extension-discovery"; -import type { LensExtensionId } from "../../../extensions/lens-extension"; import loggerInjectable from "../../../common/logger.injectable"; import extensionDiscoveryInjectable from "../../../extensions/extension-discovery/extension-discovery.injectable"; import extensionLoaderInjectable from "../../../extensions/extension-loader/extension-loader.injectable"; @@ -35,10 +33,10 @@ const initializeExtensionsInjectable = getInjectable({ // Subscribe to extensions that are copied or deleted to/from the extensions folder extensionDiscovery.events - .on("add", (extension: InstalledExtension) => { + .on("add", (extension) => { extensionLoader.addExtension(extension); }) - .on("remove", (lensExtensionId: LensExtensionId) => { + .on("remove", (lensExtensionId) => { extensionLoader.removeExtension(lensExtensionId); }); diff --git a/packages/core/src/renderer/components/+extensions/attempt-install/attempt-install.injectable.tsx b/packages/core/src/renderer/components/+extensions/attempt-install/attempt-install.injectable.tsx index 589c4b704e97..2f4f36bc3428 100644 --- a/packages/core/src/renderer/components/+extensions/attempt-install/attempt-install.injectable.tsx +++ b/packages/core/src/renderer/components/+extensions/attempt-install/attempt-install.injectable.tsx @@ -17,7 +17,6 @@ import { disposer } from "@k8slens/utilities"; import type { ShowNotification } from "../../notifications"; import { Button } from "../../button"; import type { ExtensionLoader } from "../../../../extensions/extension-loader"; -import type { LensExtensionId } from "../../../../extensions/lens-extension"; import React from "react"; import { remove as removeDir } from "fs-extra"; import { shell } from "electron"; @@ -25,6 +24,7 @@ import type { ExtensionInstallationStateStore } from "../../../../extensions/ext import { ExtensionInstallationState } from "../../../../extensions/extension-installation-state-store/extension-installation-state-store"; import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable"; import showInfoNotificationInjectable from "../../notifications/show-info-notification.injectable"; +import type { LensExtensionId } from "@k8slens/legacy-extensions"; export interface InstallRequest { fileName: string; diff --git a/packages/core/src/renderer/components/+extensions/attempt-install/create-temp-files-and-validate.injectable.tsx b/packages/core/src/renderer/components/+extensions/attempt-install/create-temp-files-and-validate.injectable.tsx index 5c1674fc94c8..fd55adce366c 100644 --- a/packages/core/src/renderer/components/+extensions/attempt-install/create-temp-files-and-validate.injectable.tsx +++ b/packages/core/src/renderer/components/+extensions/attempt-install/create-temp-files-and-validate.injectable.tsx @@ -7,13 +7,13 @@ import extensionDiscoveryInjectable from "../../../../extensions/extension-disco import { validatePackage } from "./validate-package"; import { getMessageFromError } from "../get-message-from-error/get-message-from-error"; import React from "react"; -import type { LensExtensionId, LensExtensionManifest } from "../../../../extensions/lens-extension"; import type { InstallRequest } from "./attempt-install.injectable"; import loggerInjectable from "../../../../common/logger.injectable"; import writeFileInjectable from "../../../../common/fs/write-file.injectable"; import joinPathsInjectable from "../../../../common/path/join-paths.injectable"; import tempDirectoryPathInjectable from "../../../../common/os/temp-directory-path.injectable"; import showErrorNotificationInjectable from "../../notifications/show-error-notification.injectable"; +import type { LensExtensionId, LensExtensionManifest } from "@k8slens/legacy-extensions"; export interface InstallRequestValidated { fileName: string; diff --git a/packages/core/src/renderer/components/+extensions/attempt-install/validate-package.tsx b/packages/core/src/renderer/components/+extensions/attempt-install/validate-package.tsx index ee30bda6b423..11d6cfb19aa0 100644 --- a/packages/core/src/renderer/components/+extensions/attempt-install/validate-package.tsx +++ b/packages/core/src/renderer/components/+extensions/attempt-install/validate-package.tsx @@ -2,10 +2,10 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { LensExtensionManifest } from "../../../../extensions/lens-extension"; import { hasTypedProperty, isObject, isString, listTarEntries, readFileFromTar } from "@k8slens/utilities"; import { manifestFilename } from "../../../../extensions/extension-discovery/extension-discovery"; import path from "path"; +import type { LensExtensionManifest } from "@k8slens/legacy-extensions"; export async function validatePackage(filePath: string): Promise { const tarFiles = await listTarEntries(filePath); diff --git a/packages/core/src/renderer/components/+extensions/confirm-uninstall-extension.injectable.tsx b/packages/core/src/renderer/components/+extensions/confirm-uninstall-extension.injectable.tsx index fd832e8eb413..1f30bacd5654 100644 --- a/packages/core/src/renderer/components/+extensions/confirm-uninstall-extension.injectable.tsx +++ b/packages/core/src/renderer/components/+extensions/confirm-uninstall-extension.injectable.tsx @@ -2,10 +2,9 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ +import type { LensExtensionId, InstalledExtension } from "@k8slens/legacy-extensions"; import { getInjectable } from "@ogre-tools/injectable"; import React from "react"; -import type { InstalledExtension } from "../../../extensions/extension-discovery/extension-discovery"; -import type { LensExtensionId } from "../../../extensions/lens-extension"; import { extensionDisplayName } from "../../../extensions/lens-extension"; import type { Confirm } from "../confirm-dialog/confirm.injectable"; import confirmInjectable from "../confirm-dialog/confirm.injectable"; diff --git a/packages/core/src/renderer/components/+extensions/disable-extension/disable-extension.ts b/packages/core/src/renderer/components/+extensions/disable-extension/disable-extension.ts index f7ab4de7fdab..834577a31cbf 100644 --- a/packages/core/src/renderer/components/+extensions/disable-extension/disable-extension.ts +++ b/packages/core/src/renderer/components/+extensions/disable-extension/disable-extension.ts @@ -2,7 +2,7 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { LensExtensionId } from "../../../../extensions/lens-extension"; +import type { LensExtensionId } from "@k8slens/legacy-extensions"; import type { ExtensionLoader } from "../../../../extensions/extension-loader"; interface Dependencies { diff --git a/packages/core/src/renderer/components/+extensions/enable-extension/enable-extension.ts b/packages/core/src/renderer/components/+extensions/enable-extension/enable-extension.ts index 573fa9b0376d..5692e9efdc7d 100644 --- a/packages/core/src/renderer/components/+extensions/enable-extension/enable-extension.ts +++ b/packages/core/src/renderer/components/+extensions/enable-extension/enable-extension.ts @@ -2,7 +2,7 @@ * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ -import type { LensExtensionId } from "../../../../extensions/lens-extension"; +import type { LensExtensionId } from "@k8slens/legacy-extensions"; import type { ExtensionLoader } from "../../../../extensions/extension-loader"; interface Dependencies { diff --git a/packages/core/src/renderer/components/+extensions/extensions.tsx b/packages/core/src/renderer/components/+extensions/extensions.tsx index e039822eb0f9..ab8049fe92d5 100644 --- a/packages/core/src/renderer/components/+extensions/extensions.tsx +++ b/packages/core/src/renderer/components/+extensions/extensions.tsx @@ -4,8 +4,7 @@ */ import styles from "./extensions.module.scss"; -import type { - IComputedValue } from "mobx"; +import type { IComputedValue } from "mobx"; import { makeObservable, observable, @@ -14,7 +13,6 @@ import { } from "mobx"; import { disposeOnUnmount, observer } from "mobx-react"; import React from "react"; -import type { InstalledExtension } from "../../../extensions/extension-discovery/extension-discovery"; import { DropFileInput } from "../input"; import { Install } from "./install"; import { InstalledExtensions } from "./installed-extensions"; @@ -31,13 +29,13 @@ import confirmUninstallExtensionInjectable from "./confirm-uninstall-extension.i import type { InstallExtensionFromInput } from "./install-extension-from-input.injectable"; import installExtensionFromInputInjectable from "./install-extension-from-input.injectable"; import installFromSelectFileDialogInjectable from "./install-from-select-file-dialog.injectable"; -import type { LensExtensionId } from "../../../extensions/lens-extension"; import type { InstallOnDrop } from "./install-on-drop.injectable"; import installOnDropInjectable from "./install-on-drop.injectable"; import { supportedExtensionFormats } from "./supported-extension-formats"; import extensionInstallationStateStoreInjectable from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable"; import type { ExtensionInstallationStateStore } from "../../../extensions/extension-installation-state-store/extension-installation-state-store"; import Gutter from "../gutter/gutter"; +import type { InstalledExtension, LensExtensionId } from "@k8slens/legacy-extensions"; interface Dependencies { userExtensions: IComputedValue; diff --git a/packages/core/src/renderer/components/+extensions/installed-extensions.tsx b/packages/core/src/renderer/components/+extensions/installed-extensions.tsx index 8447f0656f49..f420b63f59a4 100644 --- a/packages/core/src/renderer/components/+extensions/installed-extensions.tsx +++ b/packages/core/src/renderer/components/+extensions/installed-extensions.tsx @@ -5,10 +5,7 @@ import styles from "./installed-extensions.module.scss"; import React, { useMemo } from "react"; -import type { - ExtensionDiscovery, - InstalledExtension, -} from "../../../extensions/extension-discovery/extension-discovery"; +import type { ExtensionDiscovery } from "../../../extensions/extension-discovery/extension-discovery"; import { Icon } from "../icon"; import { List } from "../list/list"; import { MenuActions, MenuItem } from "../menu"; @@ -16,14 +13,11 @@ import { Spinner } from "../spinner"; import { cssNames } from "@k8slens/utilities"; import { observer } from "mobx-react"; import type { Row } from "react-table"; -import type { LensExtensionId } from "../../../extensions/lens-extension"; -import extensionDiscoveryInjectable - from "../../../extensions/extension-discovery/extension-discovery.injectable"; - +import extensionDiscoveryInjectable from "../../../extensions/extension-discovery/extension-discovery.injectable"; import { withInjectables } from "@ogre-tools/injectable-react"; -import extensionInstallationStateStoreInjectable - from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable"; +import extensionInstallationStateStoreInjectable from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable"; import type { ExtensionInstallationStateStore } from "../../../extensions/extension-installation-state-store/extension-installation-state-store"; +import type { InstalledExtension, LensExtensionId } from "@k8slens/legacy-extensions"; export interface InstalledExtensionsProps { extensions: InstalledExtension[]; diff --git a/packages/core/src/renderer/components/+extensions/uninstall-extension.injectable.tsx b/packages/core/src/renderer/components/+extensions/uninstall-extension.injectable.tsx index fa7cf89fb8c4..6a68107ad5f2 100644 --- a/packages/core/src/renderer/components/+extensions/uninstall-extension.injectable.tsx +++ b/packages/core/src/renderer/components/+extensions/uninstall-extension.injectable.tsx @@ -7,7 +7,7 @@ import extensionLoaderInjectable from "../../../extensions/extension-loader/exte import extensionInstallationStateStoreInjectable from "../../../extensions/extension-installation-state-store/extension-installation-state-store.injectable"; import extensionDiscoveryInjectable from "../../../extensions/extension-discovery/extension-discovery.injectable"; import loggerInjectable from "../../../common/logger.injectable"; -import type { LensExtensionId } from "../../../extensions/lens-extension"; +import type { LensExtensionId } from "@k8slens/legacy-extensions"; import { extensionDisplayName } from "../../../extensions/lens-extension"; import React from "react"; import { when } from "mobx"; diff --git a/packages/core/src/renderer/ipc/index.ts b/packages/core/src/renderer/ipc/index.ts index f8ebfc2de065..ad0a12ce2c2b 100644 --- a/packages/core/src/renderer/ipc/index.ts +++ b/packages/core/src/renderer/ipc/index.ts @@ -7,8 +7,7 @@ import { clusterActivateHandler, clusterDisconnectHandler, clusterSetFrameIdHand import type { ClusterId, ClusterState } from "../../common/cluster-types"; import { windowActionHandleChannel, windowLocationChangedChannel, windowOpenAppMenuAsContextMenuChannel, type WindowAction } from "../../common/ipc/window"; import { extensionDiscoveryStateChannel, extensionLoaderFromMainChannel } from "../../common/ipc/extension-handling"; -import type { InstalledExtension } from "../../extensions/extension-discovery/extension-discovery"; -import type { LensExtensionId } from "../../extensions/lens-extension"; +import type { InstalledExtension, LensExtensionId } from "@k8slens/legacy-extensions"; import type { Location } from "history"; import { getLegacyGlobalDiForExtensionApi } from "../../extensions/as-legacy-globals-for-extension-api/legacy-global-di-for-extension-api"; import ipcRendererInjectable from "../utils/channel/ipc-renderer.injectable"; diff --git a/packages/core/webpack/common.ts b/packages/core/webpack/common.ts deleted file mode 100644 index 2f5672c94aa8..000000000000 --- a/packages/core/webpack/common.ts +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) OpenLens Authors. All rights reserved. - * Licensed under MIT License. See LICENSE in root directory for more information. - */ - -import type webpack from "webpack"; -import path from "path"; -import ForkTsCheckerPlugin from "fork-ts-checker-webpack-plugin"; -import webpackLensMain from "./main"; -import { buildDir } from "./vars"; - -const webpackLensCommon = (): webpack.Configuration => { - const mainConfig = webpackLensMain(); - - return { - ...mainConfig, - name: "lens-app-common", - entry: { - common: path.resolve(__dirname, "..", "src", "common", "library.ts"), - }, - output: { - publicPath: "", - library: { - type: "commonjs2", - }, - path: path.resolve(buildDir, "library"), - }, - optimization: { - minimize: false, - }, - plugins: [ - new ForkTsCheckerPlugin({}), - ], - }; -}; - -export default webpackLensCommon; diff --git a/packages/core/webpack/library-bundle.ts b/packages/core/webpack/library-bundle.ts index 78d7be1bd42f..46e62960e1ff 100644 --- a/packages/core/webpack/library-bundle.ts +++ b/packages/core/webpack/library-bundle.ts @@ -3,14 +3,12 @@ * Licensed under MIT License. See LICENSE in root directory for more information. */ -import webpackLensCommon from "./common"; import webpackLensMain from "./main"; import { webpackLensRenderer } from "./renderer"; const config = [ webpackLensMain(), webpackLensRenderer(), - webpackLensCommon(), ]; export default config; diff --git a/packages/legacy-extension-example/.eslintrc.json b/packages/legacy-extension-example/.eslintrc.json new file mode 100644 index 000000000000..b15115cb694e --- /dev/null +++ b/packages/legacy-extension-example/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "@k8slens/eslint-config/eslint", + "parserOptions": { + "project": "./tsconfig.json" + } +} diff --git a/packages/legacy-extension-example/jest.config.js b/packages/legacy-extension-example/jest.config.js new file mode 100644 index 000000000000..c6074967eb6f --- /dev/null +++ b/packages/legacy-extension-example/jest.config.js @@ -0,0 +1 @@ +module.exports = require("@k8slens/jest").monorepoPackageConfig(__dirname).configForNode; diff --git a/packages/legacy-extension-example/main.ts b/packages/legacy-extension-example/main.ts new file mode 100644 index 000000000000..590990ad00cf --- /dev/null +++ b/packages/legacy-extension-example/main.ts @@ -0,0 +1,3 @@ +const noMainExtension = null; + +export default noMainExtension; diff --git a/packages/legacy-extension-example/package.json b/packages/legacy-extension-example/package.json new file mode 100644 index 000000000000..f7a07e800a13 --- /dev/null +++ b/packages/legacy-extension-example/package.json @@ -0,0 +1,46 @@ +{ + "name": "@k8slens/legacy-extension-example", + "private": false, + "description": "An example bundled Lens extensions using the v1 API", + "version": "1.0.0-alpha.0", + "type": "commonjs", + "files": [ + "dist" + ], + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/lensapp/lens.git" + }, + "exports": { + "./package.json": "./package.json", + "./main": "./dist/main.js", + "./renderer": "./dist/renderer.js" + }, + "engines": { + "lens": "6.5" + }, + "author": { + "name": "OpenLens Authors", + "email": "info@k8slens.dev" + }, + "license": "MIT", + "homepage": "https://github.com/lensapp/lens", + "scripts": { + "clean": "rimraf dist/", + "build": "webpack --config webpack.ts", + "dev": "webpack --mode=development --watch --config webpack.ts", + "test": "jest --coverage --runInBand", + "lint": "lens-lint", + "lint:fix": "lens-lint --fix" + }, + "devDependencies": { + "@types/node": "^16.18.16", + "typescript": "^4.9.5", + "webpack": "^5.76.1", + "webpack-cli": "^5.0.1" + } +} diff --git a/packages/legacy-extension-example/renderer.tsx b/packages/legacy-extension-example/renderer.tsx new file mode 100644 index 000000000000..4fe939b5c495 --- /dev/null +++ b/packages/legacy-extension-example/renderer.tsx @@ -0,0 +1,11 @@ +import { Common, Renderer } from "@k8slens/extensions"; + +export default class ExampleLensExtension extends Renderer.LensExtension { + protected onActivate(): void | Promise { + Common.logger.info("Activating bundled extension example"); + } + + protected onDeactivate(): void | Promise { + Common.logger.info("Deactivating bundled extension example"); + } +} diff --git a/packages/legacy-extension-example/tsconfig.json b/packages/legacy-extension-example/tsconfig.json new file mode 100644 index 000000000000..b4df314ca857 --- /dev/null +++ b/packages/legacy-extension-example/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@k8slens/typescript/config/base.json", + "include": ["**/*.ts", "*.ts", "*.tsx"] +} diff --git a/packages/legacy-extension-example/webpack.ts b/packages/legacy-extension-example/webpack.ts new file mode 100644 index 000000000000..e0f513dd6fcd --- /dev/null +++ b/packages/legacy-extension-example/webpack.ts @@ -0,0 +1,85 @@ +/** + * Copyright (c) OpenLens Authors. All rights reserved. + * Licensed under MIT License. See LICENSE in root directory for more information. + */ +import path from "path"; + +const webpack = [ + { + entry: "./renderer.tsx", + context: __dirname, + target: "electron-renderer", + mode: "production", + optimization: { + minimize: false, + }, + module: { + rules: [ + { + test: /\.tsx?$/, + use: "ts-loader", + exclude: /node_modules/, + }, + ], + }, + externals: [ + { + "@k8slens/extensions": "var global.LensExtensions", + react: "var global.React", + "react-dom": "var global.ReactDOM", + mobx: "var global.Mobx", + "mobx-react": "var global.MobxReact", + }, + ], + resolve: { + extensions: [".tsx", ".ts", ".js"], + }, + output: { + libraryTarget: "commonjs2", + globalObject: "this", + filename: "renderer.js", + path: path.resolve(__dirname, "dist"), + }, + }, + { + entry: "./main.ts", + context: __dirname, + target: "electron-main", + mode: "production", + optimization: { + minimize: false, + }, + module: { + rules: [ + { + test: /\.tsx?$/, + use: "ts-loader", + exclude: /node_modules/, + }, + ], + }, + externals: [ + { + "@k8slens/extensions": "var global.LensExtensions", + react: "var global.React", + "react-dom": "var global.ReactDOM", + mobx: "var global.Mobx", + "mobx-react": "var global.MobxReact", + }, + ], + resolve: { + extensions: [".tsx", ".ts", ".js"], + }, + output: { + libraryTarget: "commonjs2", + globalObject: "this", + filename: "main.js", + path: path.resolve(__dirname, "dist"), + }, + node: { + __dirname: false, + }, + }, +]; + +export default webpack; diff --git a/packages/open-lens/package.json b/packages/open-lens/package.json index 4a4588a865b0..8534ed17179a 100644 --- a/packages/open-lens/package.json +++ b/packages/open-lens/package.json @@ -201,6 +201,8 @@ "@k8slens/ensure-binaries": "^6.5.0-alpha.1", "@k8slens/feature-core": "^6.5.0-alpha.1", "@k8slens/generate-tray-icons": "^6.5.0-alpha.1", + "@k8slens/legacy-extension-example": "^1.0.0-alpha.0", + "@k8slens/legacy-extensions": "^1.0.0-alpha.0", "@k8slens/run-many": "^1.0.0-alpha.1", "@k8slens/test-utils": "^1.0.0-alpha.1", "@k8slens/utilities": "^1.0.0-alpha.1", diff --git a/packages/open-lens/src/common/example-bundled-extension.injectable.ts b/packages/open-lens/src/common/example-bundled-extension.injectable.ts new file mode 100644 index 000000000000..92cdf56cd997 --- /dev/null +++ b/packages/open-lens/src/common/example-bundled-extension.injectable.ts @@ -0,0 +1,15 @@ +import { bundledExtensionInjectionToken } from "@k8slens/legacy-extensions"; +import { getInjectable } from "@ogre-tools/injectable"; +import exampleBundledExtensionManifest from "@k8slens/legacy-extension-example/package.json"; + +const exampleBundledExtensionInjectable = getInjectable({ + id: "example-bundled-extension", + instantiate: (di) => ({ + manifest: exampleBundledExtensionManifest, + main: () => require("@k8slens/legacy-extension-example/main").default, + renderer: () => require("@k8slens/legacy-extension-example/renderer").default, + }), + injectionToken: bundledExtensionInjectionToken, +}); + +export default exampleBundledExtensionInjectable; diff --git a/packages/technical-features/application/agnostic/.eslintrc.js b/packages/technical-features/application/agnostic/.eslintrc.js deleted file mode 100644 index fae474aa7db3..000000000000 --- a/packages/technical-features/application/agnostic/.eslintrc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - extends: "@k8slens/eslint-config/eslint", - parserOptions: { - project: "./tsconfig.json", - }, -}; diff --git a/packages/technical-features/application/agnostic/.eslintrc.json b/packages/technical-features/application/agnostic/.eslintrc.json new file mode 100644 index 000000000000..b15115cb694e --- /dev/null +++ b/packages/technical-features/application/agnostic/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "@k8slens/eslint-config/eslint", + "parserOptions": { + "project": "./tsconfig.json" + } +} diff --git a/packages/technical-features/application/legacy-extensions/.eslintrc.json b/packages/technical-features/application/legacy-extensions/.eslintrc.json new file mode 100644 index 000000000000..b15115cb694e --- /dev/null +++ b/packages/technical-features/application/legacy-extensions/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "@k8slens/eslint-config/eslint", + "parserOptions": { + "project": "./tsconfig.json" + } +} diff --git a/packages/technical-features/application/legacy-extensions/README.md b/packages/technical-features/application/legacy-extensions/README.md new file mode 100644 index 000000000000..7b36bf88a7b8 --- /dev/null +++ b/packages/technical-features/application/legacy-extensions/README.md @@ -0,0 +1,5 @@ +# @k8slens/legacy-extensions + +This package contains stuff related to creating Lens-applications. + +Namely, this package contains information about extensions and bundled extensions of the v1 API. diff --git a/packages/technical-features/application/legacy-extensions/index.ts b/packages/technical-features/application/legacy-extensions/index.ts new file mode 100644 index 000000000000..f50cef0f32eb --- /dev/null +++ b/packages/technical-features/application/legacy-extensions/index.ts @@ -0,0 +1,2 @@ +export * from "./src/bundled-extension"; +export * from "./src/lens-extension"; diff --git a/packages/technical-features/application/legacy-extensions/jest.config.js b/packages/technical-features/application/legacy-extensions/jest.config.js new file mode 100644 index 000000000000..c6074967eb6f --- /dev/null +++ b/packages/technical-features/application/legacy-extensions/jest.config.js @@ -0,0 +1 @@ +module.exports = require("@k8slens/jest").monorepoPackageConfig(__dirname).configForNode; diff --git a/packages/technical-features/application/legacy-extensions/package.json b/packages/technical-features/application/legacy-extensions/package.json new file mode 100644 index 000000000000..2c427b8ef70a --- /dev/null +++ b/packages/technical-features/application/legacy-extensions/package.json @@ -0,0 +1,39 @@ +{ + "name": "@k8slens/legacy-extensions", + "private": false, + "version": "1.0.0-alpha.0", + "description": "Package for Lens extensions using the v1 API", + "type": "commonjs", + "files": [ + "dist" + ], + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/lensapp/lens.git" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "author": { + "name": "OpenLens Authors", + "email": "info@k8slens.dev" + }, + "license": "MIT", + "homepage": "https://github.com/lensapp/lens", + "scripts": { + "build": "webpack", + "dev": "webpack --mode=development --watch", + "test": "jest --coverage --runInBand", + "lint": "lens-lint", + "lint:fix": "lens-lint --fix" + }, + "peerDependencies": { + "@ogre-tools/injectable": "^15.1.2" + }, + "devDependencies": { + "@k8slens/eslint-config": "6.5.0-alpha.1" + } +} diff --git a/packages/technical-features/application/legacy-extensions/src/bundled-extension.ts b/packages/technical-features/application/legacy-extensions/src/bundled-extension.ts new file mode 100644 index 000000000000..f800ee0d376b --- /dev/null +++ b/packages/technical-features/application/legacy-extensions/src/bundled-extension.ts @@ -0,0 +1,16 @@ +import { getInjectionToken } from "@ogre-tools/injectable"; +import type { + LensExtensionConstructor, + LensExtensionManifest, +} from "./lens-extension"; + +export interface BundledExtension { + readonly manifest: LensExtensionManifest; + main: () => LensExtensionConstructor | null; + renderer: () => LensExtensionConstructor | null; +} + +export const bundledExtensionInjectionToken = + getInjectionToken({ + id: "bundled-extension-path", + }); diff --git a/packages/technical-features/application/legacy-extensions/src/lens-extension.ts b/packages/technical-features/application/legacy-extensions/src/lens-extension.ts new file mode 100644 index 000000000000..5c8222113d5d --- /dev/null +++ b/packages/technical-features/application/legacy-extensions/src/lens-extension.ts @@ -0,0 +1,63 @@ +export type LensExtensionId = string; +export type LensExtensionConstructor = new ( + ext: InstalledExtension +) => LegacyLensExtension; + +export interface InstalledExtension { + id: LensExtensionId; + + readonly manifest: LensExtensionManifest; + + // Absolute path to the non-symlinked source folder, + // e.g. "/Users/user/.k8slens/extensions/helloworld" + readonly absolutePath: string; + + /** + * Absolute to the symlinked package.json file + */ + readonly manifestPath: string; + readonly isBundled: boolean; + readonly isCompatible: boolean; + isEnabled: boolean; +} + +export interface LegacyLensExtension { + readonly id: LensExtensionId; + readonly manifest: LensExtensionManifest; + readonly manifestPath: string; + readonly isBundled: boolean; + readonly sanitizedExtensionId: string; + readonly name: string; + readonly version: string; + readonly description: string | undefined; + readonly storeName: string; + + getExtensionFileFolder(): Promise; + enable(): Promise; + disable(): Promise; + activate(): Promise; +} + +export interface LensExtensionManifest { + name: string; + version: string; + description?: string; + + main?: string; // path to %ext/dist/main.js + renderer?: string; // path to %ext/dist/renderer.js + /** + * Supported Lens version engine by extension could be defined in `manifest.engines.lens` + * Only MAJOR.MINOR version is taken in consideration. + */ + engines: { + lens: string; // "semver"-package format + npm?: string; + node?: string; + }; + + /** + * Specify extension name used for persisting data. + * Useful if extension is renamed but the data should not be lost. + */ + storeName?: string; +} diff --git a/packages/technical-features/application/legacy-extensions/tsconfig.json b/packages/technical-features/application/legacy-extensions/tsconfig.json new file mode 100644 index 000000000000..1819203dc1d3 --- /dev/null +++ b/packages/technical-features/application/legacy-extensions/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@k8slens/typescript/config/base.json", + "include": ["**/*.ts"] +} diff --git a/packages/technical-features/application/legacy-extensions/webpack.config.js b/packages/technical-features/application/legacy-extensions/webpack.config.js new file mode 100644 index 000000000000..3183f3017930 --- /dev/null +++ b/packages/technical-features/application/legacy-extensions/webpack.config.js @@ -0,0 +1 @@ +module.exports = require("@k8slens/webpack").configForNode; From 0f9927174e88a116b5ae9c0d54e2211a14a25da3 Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 15 Mar 2023 11:14:49 -0400 Subject: [PATCH 2/3] Fix build Signed-off-by: Sebastian Malton --- package-lock.json | 4 ++++ packages/legacy-extension-example/package.json | 1 + 2 files changed, 5 insertions(+) diff --git a/package-lock.json b/package-lock.json index c60e095894d8..6458fc081a39 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36380,10 +36380,14 @@ "version": "1.0.0-alpha.0", "license": "MIT", "devDependencies": { + "@k8slens/extensions": "^6.5.0-alpha.2", "@types/node": "^16.18.16", "typescript": "^4.9.5", "webpack": "^5.76.1", "webpack-cli": "^5.0.1" + }, + "engines": { + "lens": "6.5" } }, "packages/legacy-extension-example/node_modules/@types/node": { diff --git a/packages/legacy-extension-example/package.json b/packages/legacy-extension-example/package.json index f7a07e800a13..e69f56fae4cc 100644 --- a/packages/legacy-extension-example/package.json +++ b/packages/legacy-extension-example/package.json @@ -38,6 +38,7 @@ "lint:fix": "lens-lint --fix" }, "devDependencies": { + "@k8slens/extensions": "^6.5.0-alpha.2", "@types/node": "^16.18.16", "typescript": "^4.9.5", "webpack": "^5.76.1", From 99c3b3a07ad5870205cb90f7e514aaf6b4f1ef9b Mon Sep 17 00:00:00 2001 From: Sebastian Malton Date: Wed, 15 Mar 2023 11:58:32 -0400 Subject: [PATCH 3/3] Add explanatory comment for inline require Signed-off-by: Sebastian Malton --- .../src/common/example-bundled-extension.injectable.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/open-lens/src/common/example-bundled-extension.injectable.ts b/packages/open-lens/src/common/example-bundled-extension.injectable.ts index 92cdf56cd997..8b65c985fbd7 100644 --- a/packages/open-lens/src/common/example-bundled-extension.injectable.ts +++ b/packages/open-lens/src/common/example-bundled-extension.injectable.ts @@ -6,6 +6,12 @@ const exampleBundledExtensionInjectable = getInjectable({ id: "example-bundled-extension", instantiate: (di) => ({ manifest: exampleBundledExtensionManifest, + /** + * Inline `require` is needed as to delay the loading and execution of the JS file until it is needed. + * + * Futhermore there might be code that runs "during load" and shouldn't be executed until everything is + * setup for the extensions (ie globals). + */ main: () => require("@k8slens/legacy-extension-example/main").default, renderer: () => require("@k8slens/legacy-extension-example/renderer").default, }),