feat(nestjs): migrate to NestJS

This commit is contained in:
Ahmed Bouhuolia
2025-04-07 11:51:24 +02:00
parent f068218a16
commit 55fcc908ef
3779 changed files with 631 additions and 195332 deletions

View File

@@ -0,0 +1,16 @@
import { Module } from '@nestjs/common';
import { FeaturesConfigureManager } from './FeaturesConfigureManager';
import { FeaturesManager } from './FeaturesManager';
import { FeaturesSettingsDriver } from './FeaturesSettingsDriver';
import { FeaturesConfigure } from './FeaturesConfigure';
@Module({
providers: [
FeaturesManager,
FeaturesSettingsDriver,
FeaturesConfigureManager,
FeaturesConfigure
],
exports: [FeaturesManager],
})
export class FeaturesModule {}

View File

@@ -0,0 +1,31 @@
import { Features } from '@/common/types/Features';
import { IFeatureConfiugration } from '@/common/types/Features';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
@Injectable()
export class FeaturesConfigure {
constructor(private readonly configService: ConfigService) {}
/**
* Get the feature configure.
* @returns {IFeatureConfiugration[]}
*/
getConfigure(): IFeatureConfiugration[] {
return [
{
name: Features.BRANCHES,
defaultValue: false,
},
{
name: Features.WAREHOUSES,
defaultValue: false,
},
{
name: Features.BankSyncing,
defaultValue: this.configService.get('bankSync.enabled') ?? false,
},
];
}
}

View File

@@ -0,0 +1,21 @@
import { get } from 'lodash';
import { Injectable } from '@nestjs/common';
import { FeaturesConfigure } from './FeaturesConfigure';
@Injectable()
export class FeaturesConfigureManager {
constructor(private readonly featuresConfigure: FeaturesConfigure) {}
/**
* Retrieves the feature configure.
* @param {string} featureName
* @param {string} accessor
* @returns {IFeatureConfiugration}
*/
getFeatureConfigure = (featureName: string, accessor?: string) => {
const meta = this.featuresConfigure.getConfigure().find(
(feature) => feature.name === featureName
);
return accessor ? get(meta, accessor) : meta;
};
}

View File

@@ -0,0 +1,45 @@
import { Injectable } from '@nestjs/common';
import { FeaturesSettingsDriver } from './FeaturesSettingsDriver';
import { IFeatureAllItem } from '@/common/types/Features';
@Injectable()
export class FeaturesManager {
constructor(
private drive: FeaturesSettingsDriver,
) {}
/**
* Turns-on the given feature name.
* @param {string} feature
* @returns {Promise<void>}
*/
public turnOn(feature: string) {
return this.drive.turnOn(feature);
}
/**
* Turns-off the given feature name.
* @param {string} feature
* @returns {Promise<void>}
*/
public turnOff(feature: string) {
return this.drive.turnOff(feature);
}
/**
* Detarmines the given feature name is accessible.
* @param {string} feature
* @returns {Promise<void>}
*/
public async accessible(feature: string) {
return this.drive.accessible(feature);
}
/**
* Retrieves the all features and their accessible value and default value.
* @returns {Promise<IFeatureAllItem[]>}
*/
public async all(): Promise<IFeatureAllItem[]> {
return this.drive.all();
}
}

View File

@@ -0,0 +1,69 @@
import { FeaturesConfigureManager } from './FeaturesConfigureManager';
import { Inject, Injectable } from '@nestjs/common';
import { SETTINGS_PROVIDER } from '../Settings/Settings.types';
import { SettingsStore } from '../Settings/SettingsStore';
import { IFeatureAllItem } from '@/common/types/Features';
import { FeaturesConfigure } from './FeaturesConfigure';
@Injectable()
export class FeaturesSettingsDriver {
constructor(
private readonly configure: FeaturesConfigureManager,
private readonly featuresConfigure: FeaturesConfigure,
@Inject(SETTINGS_PROVIDER)
private readonly settings: () => SettingsStore,
) {}
/**
* Turns-on the given feature name.
* @param {string} feature - The feature name.
* @returns {Promise<void>}
*/
async turnOn(feature: string) {
const settingsStore = await this.settings();
settingsStore.set({ group: 'features', key: feature, value: true });
}
/**
* Turns-off the given feature name.
* @param {string} feature - The feature name.
* @returns {Promise<void>}
*/
async turnOff(feature: string) {
const settingsStore = await this.settings();
settingsStore.set({ group: 'features', key: feature, value: false });
}
/**
* Determines the given feature name is accessible.
* @param {string} feature - The feature name.
* @returns {Promise<boolean|null|undefined>}
*/
async accessible(feature: string) {
const settingsStore = await this.settings();
const defaultValue = this.configure.getFeatureConfigure(
feature,
'defaultValue',
);
return settingsStore.get({ group: 'features', key: feature }, defaultValue);
}
/**
* Retrieves the all features and their accessible value and default value.
* @returns {Promise<IFeatureAllItem>}
*/
async all(): Promise<IFeatureAllItem[]> {
const mappedOpers = this.featuresConfigure
.getConfigure()
.map(async (featureConfigure) => {
const { name, defaultValue } = featureConfigure;
const isAccessible = await this.accessible(featureConfigure.name);
return { name, isAccessible, defaultAccessible: defaultValue };
});
return Promise.all(mappedOpers);
}
}