diff --git a/packages/utility-features/app-paths/.eslintrc.json b/packages/utility-features/app-paths/.eslintrc.json new file mode 100644 index 0000000000..b15115cb69 --- /dev/null +++ b/packages/utility-features/app-paths/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "@k8slens/eslint-config/eslint", + "parserOptions": { + "project": "./tsconfig.json" + } +} diff --git a/packages/utility-features/app-paths/.prettierrc b/packages/utility-features/app-paths/.prettierrc new file mode 100644 index 0000000000..edd47b479e --- /dev/null +++ b/packages/utility-features/app-paths/.prettierrc @@ -0,0 +1 @@ +"@k8slens/eslint-config/prettier" diff --git a/packages/utility-features/app-paths/index.ts b/packages/utility-features/app-paths/index.ts new file mode 100644 index 0000000000..2fa6548c9e --- /dev/null +++ b/packages/utility-features/app-paths/index.ts @@ -0,0 +1,12 @@ +import { appPathsFeature } from "./src/feature"; + +export type { JoinPaths } from "./src/join-paths/join-paths.injectable"; +export { joinPathsInjectionToken } from "./src/join-paths/join-paths.injectable"; + +export { appPathsInjectionToken, pathNames } from "./src/app-paths-injection-token"; + +export type { AppPaths, PathName } from "./src/app-paths-injection-token"; + +export { testUtils } from "./src/test-utils"; + +export default appPathsFeature; diff --git a/packages/utility-features/app-paths/jest.config.js b/packages/utility-features/app-paths/jest.config.js new file mode 100644 index 0000000000..c6074967eb --- /dev/null +++ b/packages/utility-features/app-paths/jest.config.js @@ -0,0 +1 @@ +module.exports = require("@k8slens/jest").monorepoPackageConfig(__dirname).configForNode; diff --git a/packages/utility-features/app-paths/package.json b/packages/utility-features/app-paths/package.json new file mode 100644 index 0000000000..3e3c212a4c --- /dev/null +++ b/packages/utility-features/app-paths/package.json @@ -0,0 +1,39 @@ +{ + "name": "@k8slens/app-paths", + "private": false, + "version": "0.1.0", + "description": "TBD", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/lensapp/lens.git" + }, + "type": "commonjs", + "author": { + "name": "OpenLens Authors", + "email": "info@k8slens.dev" + }, + "license": "MIT", + "homepage": "https://github.com/lensapp/lens", + "scripts": { + "build": "lens-webpack-build", + "clean": "rimraf dist/", + "test:unit": "jest --coverage --runInBand", + "lint": "lens-lint", + "lint:fix": "lens-lint --fix" + }, + "peerDependencies": { + "@k8slens/feature-core": "^6.5.0-alpha.5", + "@ogre-tools/injectable": "^16.1.0", + "@ogre-tools/injectable-extension-for-auto-registration": "^16.1.0" + }, + "devDependencies": { + "@k8slens/eslint-config": "^6.5.0-alpha.3", + "@k8slens/react-testing-library-discovery": "^1.0.0-alpha.4", + "@k8slens/webpack": "^6.5.0-alpha.6" + } +} diff --git a/packages/utility-features/app-paths/src/app-paths-injection-token.ts b/packages/utility-features/app-paths/src/app-paths-injection-token.ts new file mode 100644 index 0000000000..689a75545d --- /dev/null +++ b/packages/utility-features/app-paths/src/app-paths-injection-token.ts @@ -0,0 +1,28 @@ +import { getInjectionToken } from "@ogre-tools/injectable"; + +export const pathNames = [ + "home", + "appData", + "userData", + "cache", + "temp", + "exe", + "module", + "desktop", + "documents", + "downloads", + "music", + "pictures", + "videos", + "logs", + "crashDumps", + "recent", +] as const; + +export type PathName = (typeof pathNames)[number]; + +export type AppPaths = Record; + +export const appPathsInjectionToken = getInjectionToken({ + id: "app-paths-token", +}); diff --git a/packages/utility-features/app-paths/src/feature.ts b/packages/utility-features/app-paths/src/feature.ts new file mode 100644 index 0000000000..8a5536d7f0 --- /dev/null +++ b/packages/utility-features/app-paths/src/feature.ts @@ -0,0 +1,15 @@ +import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration"; +import { getFeature } from "@k8slens/feature-core"; + +export const appPathsFeature = getFeature({ + id: "app-paths", + + register: (di) => { + autoRegister({ + di, + targetModule: module, + + getRequireContexts: () => [require.context("./", true, /\.injectable\.(ts|tsx)$/)], + }); + }, +}); diff --git a/packages/utility-features/app-paths/src/join-paths/join-paths.injectable.ts b/packages/utility-features/app-paths/src/join-paths/join-paths.injectable.ts new file mode 100644 index 0000000000..1d7234dd89 --- /dev/null +++ b/packages/utility-features/app-paths/src/join-paths/join-paths.injectable.ts @@ -0,0 +1,20 @@ +import { getInjectable, getInjectionToken } from "@ogre-tools/injectable"; +import path from "path"; + +export type JoinPaths = (...args: string[]) => string; + +export const joinPathsInjectionToken = getInjectionToken({ + id: "join-paths-injection-token", +}); + +const joinPathsInjectable = getInjectable({ + id: "join-paths", + instantiate: (): JoinPaths => path.join, + + // This causes side effect e.g. Windows uses different separator than e.g. linux + causesSideEffects: true, + + injectionToken: joinPathsInjectionToken, +}); + +export default joinPathsInjectable; diff --git a/packages/utility-features/app-paths/src/join-paths/join-paths.test.ts b/packages/utility-features/app-paths/src/join-paths/join-paths.test.ts new file mode 100644 index 0000000000..b08da1e21d --- /dev/null +++ b/packages/utility-features/app-paths/src/join-paths/join-paths.test.ts @@ -0,0 +1,20 @@ +import { createContainer, DiContainer } from "@ogre-tools/injectable"; +import { registerFeature } from "@k8slens/feature-core"; +import { joinPathsInjectionToken } from "./join-paths.injectable"; +import { appPathsFeature } from "../feature"; +import path from "path"; + +describe("join-paths", () => { + let di: DiContainer; + let joinPaths: (...args: string[]) => string; + + beforeEach(() => { + di = createContainer("irrelevant"); + registerFeature(di, appPathsFeature); + joinPaths = di.inject(joinPathsInjectionToken); + }); + + it("is the native function", () => { + expect(joinPaths).toBe(path.join); + }); +}); diff --git a/packages/utility-features/app-paths/src/test-utils/index.ts b/packages/utility-features/app-paths/src/test-utils/index.ts new file mode 100644 index 0000000000..e72d980167 --- /dev/null +++ b/packages/utility-features/app-paths/src/test-utils/index.ts @@ -0,0 +1,40 @@ +import type { DiContainer } from "@ogre-tools/injectable"; +import joinPathsInjectable from "../join-paths/join-paths.injectable"; +import path from "path"; +import { getInjectable } from "@ogre-tools/injectable"; +import { appPathsInjectionToken } from "../app-paths-injection-token"; + +const doGlobalOverrides = (di: DiContainer) => { + // Note: implementation of app-paths is still in OpenLens. + // Therefore, a stub is registered in its place to serve spirit of unit testing. + const appPathsStubInjectable = getInjectable({ + id: "app-paths-stub", + + instantiate: () => ({ + appData: "some-app-data-directory", + cache: "some-cache-directory", + crashDumps: "some-crash-dumps-directory", + desktop: "some-desktop-directory", + documents: "some-documents-directory", + downloads: "some-downloads-directory", + exe: "some-exe-directory", + home: "some-home-directory", + logs: "some-logs-directory", + module: "some-module-directory", + music: "some-music-directory", + pictures: "some-pictures-directory", + recent: "some-recent-directory", + temp: "some-temp-directory", + videos: "some-videos-directory", + userData: "some-user-data-directory", + }), + + injectionToken: appPathsInjectionToken, + }); + + di.register(appPathsStubInjectable); + + di.override(joinPathsInjectable, () => path.posix.join); +}; + +export const testUtils = { doGlobalOverrides }; diff --git a/packages/utility-features/app-paths/tsconfig.json b/packages/utility-features/app-paths/tsconfig.json new file mode 100644 index 0000000000..1819203dc1 --- /dev/null +++ b/packages/utility-features/app-paths/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "@k8slens/typescript/config/base.json", + "include": ["**/*.ts"] +} diff --git a/packages/utility-features/app-paths/webpack.config.js b/packages/utility-features/app-paths/webpack.config.js new file mode 100644 index 0000000000..3183f30179 --- /dev/null +++ b/packages/utility-features/app-paths/webpack.config.js @@ -0,0 +1 @@ +module.exports = require("@k8slens/webpack").configForNode;