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

Start using eslint and prettier in packages

Co-authored-by: Mikko Aspiala <mikko.aspiala@gmail.com>

Signed-off-by: Janne Savolainen <janne.savolainen@live.fi>
This commit is contained in:
Janne Savolainen 2023-03-07 15:50:51 +02:00
parent 4b78f62be8
commit 8eebb6394f
No known key found for this signature in database
GPG Key ID: 8C6CFB2FFFE8F68A
31 changed files with 167 additions and 191 deletions

5
package-lock.json generated
View File

@ -34981,6 +34981,7 @@
} }
}, },
"packages/infrastructure/eslint-config": { "packages/infrastructure/eslint-config": {
"name": "@k8slens/eslint-config",
"version": "^6.5.0-alpha.0", "version": "^6.5.0-alpha.0",
"license": "MIT", "license": "MIT",
"bin": { "bin": {
@ -37032,6 +37033,7 @@
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@async-fn/jest": "^1.6.4", "@async-fn/jest": "^1.6.4",
"@k8slens/eslint-config": "*",
"@ogre-tools/test-utils": "^15.1.2" "@ogre-tools/test-utils": "^15.1.2"
}, },
"peerDependencies": { "peerDependencies": {
@ -37046,6 +37048,9 @@
"name": "@k8slens/feature-core", "name": "@k8slens/feature-core",
"version": "6.5.0-alpha.0", "version": "6.5.0-alpha.0",
"license": "MIT", "license": "MIT",
"devDependencies": {
"@k8slens/eslint-config": "*"
},
"peerDependencies": { "peerDependencies": {
"@ogre-tools/injectable": "^15.1.2" "@ogre-tools/injectable": "^15.1.2"
} }

View File

@ -0,0 +1,6 @@
module.exports = {
extends: "@k8slens/eslint-config/eslint",
parserOptions: {
project: "./tsconfig.json",
},
};

View File

@ -0,0 +1 @@
"@k8slens/eslint-config/prettier"

View File

@ -1,2 +1 @@
module.exports = module.exports = require("@k8slens/jest").monorepoPackageConfig(__dirname).configForNode;
require("@k8slens/jest").monorepoPackageConfig(__dirname).configForNode;

View File

@ -26,7 +26,9 @@
"scripts": { "scripts": {
"build": "webpack", "build": "webpack",
"dev": "webpack --mode=development --watch", "dev": "webpack --mode=development --watch",
"test": "jest --coverage --runInBand" "test": "jest --coverage --runInBand",
"lint": "lens-lint",
"lint:fix": "lens-lint --fix"
}, },
"peerDependencies": { "peerDependencies": {
"@k8slens/feature-core": "^6.5.0-alpha.0", "@k8slens/feature-core": "^6.5.0-alpha.0",
@ -37,6 +39,7 @@
}, },
"devDependencies": { "devDependencies": {
"@async-fn/jest": "^1.6.4" "@async-fn/jest": "^1.6.4",
"@k8slens/eslint-config": "*"
} }
} }

View File

@ -10,15 +10,15 @@ export type ApplicationInformation = {
productName: string; productName: string;
copyright: string; copyright: string;
description: string; description: string;
k8sProxyVersion: string, k8sProxyVersion: string;
bundledKubectlVersion: string, bundledKubectlVersion: string;
bundledHelmVersion: string, bundledHelmVersion: string;
sentryDsn: string, sentryDsn: string;
contentSecurityPolicy: string, contentSecurityPolicy: string;
welcomeRoute: string, welcomeRoute: string;
updatingIsEnabled: boolean; updatingIsEnabled: boolean;
dependencies: Partial<Record<string, string>>; dependencies: Partial<Record<string, string>>;
} };
export const applicationInformationToken = getInjectionToken<ApplicationInformation>({ export const applicationInformationToken = getInjectionToken<ApplicationInformation>({
id: "application-information-token", id: "application-information-token",

View File

@ -9,9 +9,7 @@ export const applicationFeature = getFeature({
di, di,
targetModule: module, targetModule: module,
getRequireContexts: () => [ getRequireContexts: () => [require.context("./", true, /\.injectable\.(ts|tsx)$/)],
require.context("./", true, /\.injectable\.(ts|tsx)$/),
],
}); });
}, },
}); });

View File

@ -1,8 +1,4 @@
import { import { createContainer, DiContainer, getInjectable } from "@ogre-tools/injectable";
createContainer,
DiContainer,
getInjectable,
} from "@ogre-tools/injectable";
import { registerFeature } from "@k8slens/feature-core"; import { registerFeature } from "@k8slens/feature-core";
import { applicationFeature } from "../feature"; import { applicationFeature } from "../feature";
import { startApplicationInjectionToken } from "./start-application.injectable"; import { startApplicationInjectionToken } from "./start-application.injectable";
@ -46,7 +42,7 @@ describe("starting-of-application", () => {
di.register( di.register(
beforeApplicationIsLoadingInjectable, beforeApplicationIsLoadingInjectable,
onLoadOfApplicationInjectable, onLoadOfApplicationInjectable,
afterApplicationIsLoadedInjectable afterApplicationIsLoadedInjectable,
); );
}); });
@ -54,7 +50,7 @@ describe("starting-of-application", () => {
beforeEach(() => { beforeEach(() => {
const startApplication = di.inject(startApplicationInjectionToken); const startApplication = di.inject(startApplicationInjectionToken);
startApplication(); void startApplication();
}); });
it("calls runnables registered in before application is loading", () => { it("calls runnables registered in before application is loading", () => {

View File

@ -1,3 +1,4 @@
{ {
"extends": "@k8slens/typescript/config/base.json" "extends": "@k8slens/typescript/config/base.json",
"include": ["**/*.ts"]
} }

View File

@ -0,0 +1,6 @@
module.exports = {
extends: "@k8slens/eslint-config/eslint",
parserOptions: {
project: "./tsconfig.json",
},
};

View File

@ -0,0 +1 @@
"@k8slens/eslint-config/prettier"

View File

@ -4,4 +4,4 @@ export * from "./src/start-application/time-slots";
export { applicationFeatureForElectronMain } from "./src/feature"; export { applicationFeatureForElectronMain } from "./src/feature";
export const testUtils = { overrideSideEffectsWithFakes } export const testUtils = { overrideSideEffectsWithFakes };

View File

@ -1,2 +1 @@
module.exports = module.exports = require("@k8slens/jest").monorepoPackageConfig(__dirname).configForNode;
require("@k8slens/jest").monorepoPackageConfig(__dirname).configForNode;

View File

@ -26,7 +26,9 @@
"scripts": { "scripts": {
"build": "webpack", "build": "webpack",
"dev": "webpack --mode=development --watch", "dev": "webpack --mode=development --watch",
"test": "jest --coverage --runInBand" "test": "jest --coverage --runInBand",
"lint": "lens-lint",
"lint:fix": "lens-lint --fix"
}, },
"peerDependencies": { "peerDependencies": {
"@k8slens/feature-core": "^6.5.0-alpha.0", "@k8slens/feature-core": "^6.5.0-alpha.0",
@ -38,6 +40,7 @@
"devDependencies": { "devDependencies": {
"@async-fn/jest": "^1.6.4", "@async-fn/jest": "^1.6.4",
"@ogre-tools/test-utils": "^15.1.2" "@ogre-tools/test-utils": "^15.1.2",
"@k8slens/eslint-config": "*"
} }
} }

View File

@ -1,14 +1,14 @@
import electronAppInjectable from "./electron-app.injectable"; import electronAppInjectable from "./electron-app.injectable";
import { app } from 'electron'; import { app } from "electron";
import { createContainer } from "@ogre-tools/injectable"; import { createContainer } from "@ogre-tools/injectable";
import { applicationFeatureForElectronMain } from "../feature"; import { applicationFeatureForElectronMain } from "../feature";
import { registerFeature } from "@k8slens/feature-core"; import { registerFeature } from "@k8slens/feature-core";
describe('electron-app', () => { describe("electron-app", () => {
it('is electron app', () => { it("is electron app", () => {
const di = createContainer('irrelevant'); const di = createContainer("irrelevant");
registerFeature(di, applicationFeatureForElectronMain) registerFeature(di, applicationFeatureForElectronMain);
const actual = di.inject(electronAppInjectable); const actual = di.inject(electronAppInjectable);

View File

@ -1,6 +1,6 @@
import { getFeature } from "@k8slens/feature-core"; import { getFeature } from "@k8slens/feature-core";
import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration"; import { autoRegister } from "@ogre-tools/injectable-extension-for-auto-registration";
import { applicationFeature } from '@k8slens/application'; import { applicationFeature } from "@k8slens/application";
export const applicationFeatureForElectronMain = getFeature({ export const applicationFeatureForElectronMain = getFeature({
id: "application-for-electron-main", id: "application-for-electron-main",
@ -10,13 +10,9 @@ export const applicationFeatureForElectronMain = getFeature({
di, di,
targetModule: module, targetModule: module,
getRequireContexts: () => [ getRequireContexts: () => [require.context("./", true, /\.injectable\.(ts|tsx)$/)],
require.context("./", true, /\.injectable\.(ts|tsx)$/),
],
}); });
}, },
dependencies: [ dependencies: [applicationFeature],
applicationFeature
]
}); });

View File

@ -2,5 +2,5 @@ import type { DiContainer } from "@ogre-tools/injectable";
import whenAppIsReadyInjectable from "./start-application/when-app-is-ready.injectable"; import whenAppIsReadyInjectable from "./start-application/when-app-is-ready.injectable";
export const overrideSideEffectsWithFakes = (di: DiContainer) => { export const overrideSideEffectsWithFakes = (di: DiContainer) => {
di.override(whenAppIsReadyInjectable, () => () => Promise.resolve()) di.override(whenAppIsReadyInjectable, () => () => Promise.resolve());
}; };

View File

@ -18,10 +18,7 @@ describe("when-app-is-ready", () => {
whenReadyMock = asyncFn(); whenReadyMock = asyncFn();
di.override( di.override(electronAppInjectable, () => ({ whenReady: whenReadyMock } as unknown));
electronAppInjectable,
() => ({ whenReady: whenReadyMock } as unknown)
);
}); });
describe("when called", () => { describe("when called", () => {

View File

@ -1,8 +1,4 @@
import { import { createContainer, DiContainer, getInjectable } from "@ogre-tools/injectable";
createContainer,
DiContainer,
getInjectable,
} from "@ogre-tools/injectable";
import { registerFeature } from "@k8slens/feature-core"; import { registerFeature } from "@k8slens/feature-core";
import { applicationFeatureForElectronMain } from "./feature"; import { applicationFeatureForElectronMain } from "./feature";
import { import {
@ -52,7 +48,7 @@ describe("starting-of-electron-main-application", () => {
di.register( di.register(
beforeAnythingIsLoadingInjectable, beforeAnythingIsLoadingInjectable,
beforeElectronIsReadyIsLoadingInjectable, beforeElectronIsReadyIsLoadingInjectable,
beforeApplicationIsLoadingInjectable beforeApplicationIsLoadingInjectable,
); );
di.override(whenAppIsReadyInjectable, () => whenAppIsReadyMock); di.override(whenAppIsReadyInjectable, () => whenAppIsReadyMock);
@ -62,7 +58,7 @@ describe("starting-of-electron-main-application", () => {
beforeEach(() => { beforeEach(() => {
const startApplication = di.inject(startApplicationInjectionToken); const startApplication = di.inject(startApplicationInjectionToken);
startApplication(); void startApplication();
}); });
it("calls for synchronous runnables for before anything", () => { it("calls for synchronous runnables for before anything", () => {

View File

@ -1,3 +1,4 @@
{ {
"extends": "@k8slens/typescript/config/base.json" "extends": "@k8slens/typescript/config/base.json",
"include": ["**/*.ts"]
} }

View File

@ -0,0 +1,6 @@
module.exports = {
extends: "@k8slens/eslint-config/eslint",
parserOptions: {
project: "./tsconfig.json",
},
};

View File

@ -0,0 +1 @@
"@k8slens/eslint-config/prettier"

View File

@ -1,2 +1 @@
module.exports = module.exports = require("@k8slens/jest").monorepoPackageConfig(__dirname).configForReact;
require("@k8slens/jest").monorepoPackageConfig(__dirname).configForReact;

View File

@ -28,9 +28,15 @@
"scripts": { "scripts": {
"build": "webpack", "build": "webpack",
"dev": "webpack --mode=development --watch", "dev": "webpack --mode=development --watch",
"test": "jest --coverage --runInBand" "test": "jest --coverage --runInBand",
"lint": "lens-lint",
"lint:fix": "lens-lint --fix"
}, },
"peerDependencies": { "peerDependencies": {
"@ogre-tools/injectable": "^15.1.2" "@ogre-tools/injectable": "^15.1.2"
},
"devDependencies": {
"@k8slens/eslint-config": "*"
} }
} }

View File

@ -2,25 +2,31 @@ import type { DiContainer } from "@ogre-tools/injectable";
import type { Feature } from "./feature"; import type { Feature } from "./feature";
import { featureContextMapInjectable } from "./feature-context-map-injectable"; import { featureContextMapInjectable } from "./feature-context-map-injectable";
export const deregisterFeature = (di: DiContainer, ...features: Feature[]) => { const getDependingFeaturesFor = (
features.forEach((feature) => { featureContextMap: Map<Feature, { dependedBy: Map<Feature, number> }>,
deregisterFeatureRecursed(di, feature); ) => {
}); const getDependingFeaturesForRecursion = (feature: Feature, atRoot = true): string[] => {
const context = featureContextMap.get(feature);
if (context?.dependedBy.size) {
return [...context?.dependedBy.entries()].flatMap(([dependant]) =>
getDependingFeaturesForRecursion(dependant, false),
);
}
return atRoot ? [] : [feature.id];
};
return getDependingFeaturesForRecursion;
}; };
const deregisterFeatureRecursed = ( const deregisterFeatureRecursed = (di: DiContainer, feature: Feature, dependedBy?: Feature) => {
di: DiContainer,
feature: Feature,
dependedBy?: Feature
) => {
const featureContextMap = di.inject(featureContextMapInjectable); const featureContextMap = di.inject(featureContextMapInjectable);
const featureContext = featureContextMap.get(feature); const featureContext = featureContextMap.get(feature);
if (!featureContext) { if (!featureContext) {
throw new Error( throw new Error(`Tried to deregister feature "${feature.id}", but it was not registered.`);
`Tried to deregister feature "${feature.id}", but it was not registered.`
);
} }
featureContext.numberOfRegistrations--; featureContext.numberOfRegistrations--;
@ -33,15 +39,15 @@ const deregisterFeatureRecursed = (
throw new Error( throw new Error(
`Tried to deregister Feature "${ `Tried to deregister Feature "${
feature.id feature.id
}", but it is the dependency of Features "${dependingFeatures.join( }", but it is the dependency of Features "${dependingFeatures.join(", ")}"`,
", "
)}"`
); );
} }
if (dependedBy) { if (dependedBy) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const oldNumberOfDependents = featureContext.dependedBy.get(dependedBy)!; const oldNumberOfDependents = featureContext.dependedBy.get(dependedBy)!;
const newNumberOfDependants = oldNumberOfDependents - 1; const newNumberOfDependants = oldNumberOfDependents - 1;
featureContext.dependedBy.set(dependedBy, newNumberOfDependants); featureContext.dependedBy.set(dependedBy, newNumberOfDependants);
if (newNumberOfDependants === 0) { if (newNumberOfDependants === 0) {
@ -60,23 +66,8 @@ const deregisterFeatureRecursed = (
}); });
}; };
const getDependingFeaturesFor = ( export const deregisterFeature = (di: DiContainer, ...features: Feature[]) => {
featureContextMap: Map<Feature, { dependedBy: Map<Feature, number> }> features.forEach((feature) => {
) => { deregisterFeatureRecursed(di, feature);
const getDependingFeaturesForRecursion = ( });
feature: Feature,
atRoot = true
): string[] => {
const context = featureContextMap.get(feature);
if (context?.dependedBy.size) {
return [...context!.dependedBy.entries()].flatMap(([dependant]) =>
getDependingFeaturesForRecursion(dependant, false)
);
}
return atRoot ? [] : [feature.id];
};
return getDependingFeaturesForRecursion;
}; };

View File

@ -11,10 +11,9 @@ export type FeatureContextMap = Map<
} }
>; >;
export const featureContextMapInjectionToken = export const featureContextMapInjectionToken = getInjectionToken<FeatureContextMap>({
getInjectionToken<FeatureContextMap>({ id: "feature-context-map-injection-token",
id: "feature-context-map-injection-token", });
});
const featureContextMapInjectable = getInjectable({ const featureContextMapInjectable = getInjectable({
id: "feature-store", id: "feature-store",

View File

@ -1,14 +1,9 @@
import { import { createContainer, DiContainer, getInjectable, Injectable } from "@ogre-tools/injectable";
createContainer,
DiContainer,
getInjectable,
Injectable,
} from "@ogre-tools/injectable";
import type { Feature } from "./feature"; import type { Feature } from "./feature";
import { registerFeature } from "./register-feature"; import { registerFeature } from "./register-feature";
import { deregisterFeature } from "./deregister-feature"; import { deregisterFeature } from "./deregister-feature";
import { getFeature } from "./feature" ; import { getFeature } from "./feature";
describe("feature-dependencies", () => { describe("feature-dependencies", () => {
describe("given a parent Feature with another Features as dependency", () => { describe("given a parent Feature with another Features as dependency", () => {
@ -55,7 +50,7 @@ describe("feature-dependencies", () => {
expect(() => { expect(() => {
deregisterFeature(di, someDependencyFeature); deregisterFeature(di, someDependencyFeature);
}).toThrow( }).toThrow(
'Tried to deregister Feature "some-dependency-feature", but it is the dependency of Features "some-feature"' 'Tried to deregister Feature "some-dependency-feature", but it is the dependency of Features "some-feature"',
); );
}); });
@ -65,7 +60,7 @@ describe("feature-dependencies", () => {
expect(() => { expect(() => {
deregisterFeature(di, someDependencyFeature); deregisterFeature(di, someDependencyFeature);
}).toThrow( }).toThrow(
'Tried to deregister feature "some-dependency-feature", but it was not registered.' 'Tried to deregister feature "some-dependency-feature", but it was not registered.',
); );
}); });
@ -74,9 +69,7 @@ describe("feature-dependencies", () => {
expect(() => { expect(() => {
di.inject(someInjectableInDependencyFeature); di.inject(someInjectableInDependencyFeature);
}).toThrow( }).toThrow('Tried to inject non-registered injectable "irrelevant" -> "some-injectable".');
'Tried to inject non-registered injectable "irrelevant" -> "some-injectable".'
);
}); });
}); });
@ -112,7 +105,7 @@ describe("feature-dependencies", () => {
expect(() => { expect(() => {
deregisterFeature(di, someFeature1); deregisterFeature(di, someFeature1);
}).toThrow( }).toThrow(
'Tried to deregister Feature "some-feature-1", but it is the dependency of Features "some-feature-2"' 'Tried to deregister Feature "some-feature-1", but it is the dependency of Features "some-feature-2"',
); );
}); });
@ -170,7 +163,7 @@ describe("feature-dependencies", () => {
expect(() => { expect(() => {
deregisterFeature(di, someSharedDependencyFeature); deregisterFeature(di, someSharedDependencyFeature);
}).toThrow( }).toThrow(
'Tried to deregister Feature "some-dependency-feature", but it is the dependency of Features "some-feature-1, some-feature-2"' 'Tried to deregister Feature "some-dependency-feature", but it is the dependency of Features "some-feature-1, some-feature-2"',
); );
}); });
@ -188,7 +181,7 @@ describe("feature-dependencies", () => {
expect(() => { expect(() => {
di.inject(someInjectableInDependencyFeature); di.inject(someInjectableInDependencyFeature);
}).toThrow( }).toThrow(
'Tried to inject non-registered injectable "irrelevant" -> "some-injectable-in-dependency-feature".' 'Tried to inject non-registered injectable "irrelevant" -> "some-injectable-in-dependency-feature".',
); );
}); });
}); });
@ -231,19 +224,14 @@ describe("feature-dependencies", () => {
dependencies: [someFeatureForAdditionalHierarchy], dependencies: [someFeatureForAdditionalHierarchy],
}); });
registerFeature( registerFeature(di, someFeature1, someFeature2, someSharedDependencyFeature);
di,
someFeature1,
someFeature2,
someSharedDependencyFeature
);
}); });
it("when the shared Feature is deregistered, throws", () => { it("when the shared Feature is deregistered, throws", () => {
expect(() => { expect(() => {
deregisterFeature(di, someSharedDependencyFeature); deregisterFeature(di, someSharedDependencyFeature);
}).toThrow( }).toThrow(
'Tried to deregister Feature "some-dependency-feature", but it is the dependency of Features "some-feature-1, some-feature-2"' 'Tried to deregister Feature "some-dependency-feature", but it is the dependency of Features "some-feature-1, some-feature-2"',
); );
}); });
@ -264,17 +252,12 @@ describe("feature-dependencies", () => {
}); });
it("given all of the Features get deregistered, when injecting an injectable from the shared Feature, throws", () => { it("given all of the Features get deregistered, when injecting an injectable from the shared Feature, throws", () => {
deregisterFeature( deregisterFeature(di, someFeature1, someFeature2, someSharedDependencyFeature);
di,
someFeature1,
someFeature2,
someSharedDependencyFeature
);
expect(() => { expect(() => {
di.inject(someInjectableInDependencyFeature); di.inject(someInjectableInDependencyFeature);
}).toThrow( }).toThrow(
'Tried to inject non-registered injectable "irrelevant" -> "some-injectable-in-dependency-feature".' 'Tried to inject non-registered injectable "irrelevant" -> "some-injectable-in-dependency-feature".',
); );
}); });
}); });

View File

@ -8,5 +8,4 @@ export interface Feature {
export interface GetFeatureArgs extends Feature {} export interface GetFeatureArgs extends Feature {}
export const getFeature = (getFeatureArgs: GetFeatureArgs): Feature => export const getFeature = (getFeatureArgs: GetFeatureArgs): Feature => getFeatureArgs;
getFeatureArgs;

View File

@ -6,58 +6,6 @@ import {
featureContextMapInjectionToken, featureContextMapInjectionToken,
} from "./feature-context-map-injectable"; } from "./feature-context-map-injectable";
export const registerFeature = (di: DiContainer, ...features: Feature[]) => {
features.forEach((feature) => {
registerFeatureRecursed(di, feature);
});
};
const registerFeatureRecursed = (
di: DiContainer,
feature: Feature,
dependedBy?: Feature
) => {
const featureContextMaps = di.injectMany(featureContextMapInjectionToken);
if (featureContextMaps.length === 0) {
di.register(featureContextMapInjectable);
}
const featureContextMap = di.inject(featureContextMapInjectable);
const existingFeatureContext = featureContextMap.get(feature);
if (
!dependedBy &&
existingFeatureContext &&
existingFeatureContext.dependedBy.size === 0
) {
throw new Error(
`Tried to register feature "${feature.id}", but it was already registered.`
);
}
const featureContext =
existingFeatureContext || createFeatureContext(feature, di);
featureContext.numberOfRegistrations++;
if (dependedBy) {
const oldNumberOfDependents =
featureContext.dependedBy.get(dependedBy) || 0;
const newNumberOfDependants = oldNumberOfDependents + 1;
featureContext.dependedBy.set(dependedBy, newNumberOfDependants);
}
if (!existingFeatureContext) {
featureContext.register();
}
feature.dependencies?.forEach((dependency) => {
registerFeatureRecursed(di, dependency, feature);
});
};
const createFeatureContext = (feature: Feature, di: DiContainer) => { const createFeatureContext = (feature: Feature, di: DiContainer) => {
const featureContextInjectable = getInjectable({ const featureContextInjectable = getInjectable({
id: feature.id, id: feature.id,
@ -88,3 +36,45 @@ const createFeatureContext = (feature: Feature, di: DiContainer) => {
return featureContext; return featureContext;
}; };
const registerFeatureRecursed = (di: DiContainer, feature: Feature, dependedBy?: Feature) => {
const featureContextMaps = di.injectMany(featureContextMapInjectionToken);
if (featureContextMaps.length === 0) {
di.register(featureContextMapInjectable);
}
const featureContextMap = di.inject(featureContextMapInjectable);
const existingFeatureContext = featureContextMap.get(feature);
if (!dependedBy && existingFeatureContext && existingFeatureContext.dependedBy.size === 0) {
throw new Error(`Tried to register feature "${feature.id}", but it was already registered.`);
}
const featureContext = existingFeatureContext || createFeatureContext(feature, di);
featureContext.numberOfRegistrations++;
if (dependedBy) {
const oldNumberOfDependents = featureContext.dependedBy.get(dependedBy) || 0;
const newNumberOfDependants = oldNumberOfDependents + 1;
featureContext.dependedBy.set(dependedBy, newNumberOfDependants);
}
if (!existingFeatureContext) {
featureContext.register();
}
feature.dependencies?.forEach((dependency) => {
registerFeatureRecursed(di, dependency, feature);
});
};
export const registerFeature = (di: DiContainer, ...features: Feature[]) => {
features.forEach((feature) => {
registerFeatureRecursed(di, feature);
});
};

View File

@ -1,10 +1,5 @@
import { registerFeature } from "./register-feature"; import { registerFeature } from "./register-feature";
import { import { createContainer, DiContainer, getInjectable, Injectable } from "@ogre-tools/injectable";
createContainer,
DiContainer,
getInjectable,
Injectable,
} from "@ogre-tools/injectable";
import type { Feature } from "./feature"; import type { Feature } from "./feature";
import { getFeature } from "./feature"; import { getFeature } from "./feature";
import { deregisterFeature } from "./deregister-feature"; import { deregisterFeature } from "./deregister-feature";
@ -90,9 +85,7 @@ describe("register-feature", () => {
it("when a Feature is registered again, throws", () => { it("when a Feature is registered again, throws", () => {
expect(() => { expect(() => {
registerFeature(di, someFeature); registerFeature(di, someFeature);
}).toThrow( }).toThrow('Tried to register feature "some-feature-1", but it was already registered.');
'Tried to register feature "some-feature-1", but it was already registered.'
);
}); });
it("given a Feature deregistered, when deregistered again, throws", () => { it("given a Feature deregistered, when deregistered again, throws", () => {
@ -100,15 +93,14 @@ describe("register-feature", () => {
expect(() => { expect(() => {
deregisterFeature(di, someFeature); deregisterFeature(di, someFeature);
}).toThrow( }).toThrow('Tried to deregister feature "some-feature-1", but it was not registered.');
'Tried to deregister feature "some-feature-1", but it was not registered.'
);
}); });
}); });
it("given di-container and registered Features with injectables forming a cycle, when an injectable is injected, throws with namespaced error about cycle", () => { it("given di-container and registered Features with injectables forming a cycle, when an injectable is injected, throws with namespaced error about cycle", () => {
const someInjectable: Injectable<any> = getInjectable({ const someInjectable: Injectable<any> = getInjectable({
id: "some-injectable-1", id: "some-injectable-1",
// eslint-disable-next-line @typescript-eslint/no-use-before-define
instantiate: (di) => di.inject(someInjectable2), instantiate: (di) => di.inject(someInjectable2),
}); });
@ -140,8 +132,9 @@ describe("register-feature", () => {
expect(() => { expect(() => {
di.inject(someInjectable); di.inject(someInjectable);
}).toThrow( }).toThrow(
// 'Cycle of injectables encountered: "some-container" -> "some-feature-1:some-injectable-1" -> "some-feature-2:some-injectable-2" -> "some-feature-1:some-injectable-1"' // 'Cycle of injectables encountered: "some-container" -> "some-feature-1:some-injectable-1"
'Maximum call stack size exceeded' // -> "some-feature-2:some-injectable-2" -> "some-feature-1:some-injectable-1"'
"Maximum call stack size exceeded",
); );
}); });
}); });

View File

@ -1,3 +1,4 @@
{ {
"extends": "@k8slens/typescript/config/base.json" "extends": "@k8slens/typescript/config/base.json",
"include": ["**/*.ts"]
} }