diff --git a/services/feature-toggle-service/README.md b/services/feature-toggle-service/README.md index f03373bf43..52ee83f637 100644 --- a/services/feature-toggle-service/README.md +++ b/services/feature-toggle-service/README.md @@ -49,6 +49,21 @@ npm i @sourceloop/feature-toggle-service - Start the application `npm start` +### Using with Sequelize + +This service supports Sequelize as the underlying ORM using [@loopback/sequelize](https://www.npmjs.com/package/@loopback/sequelize) extension. And in order to use it, you'll need to do following changes. + +1. To use Sequelize in your application, add following to application.ts: + +```ts +this.bind(FeatureToggleBindings.Config).to({ + bindControllers: true, + useCustomSequence: false, +}); +``` + +2. Use the `SequelizeDataSource` in your audit datasource as the parent class. Refer [this](https://www.npmjs.com/package/@loopback/sequelize#step-1-configure-datasource) for more. + ### Asymmetric Token Signing and Verification If you are using asymmetric token signing and verification, you need to create a datasource for auth database. Example datasource file for auth:- diff --git a/services/feature-toggle-service/package.json b/services/feature-toggle-service/package.json index 16cbf4818f..1f0c48e951 100644 --- a/services/feature-toggle-service/package.json +++ b/services/feature-toggle-service/package.json @@ -96,6 +96,9 @@ "typescript": "^5.4.5", "widdershins": "^4.0.1" }, + "optionalDependencies": { + "@loopback/sequelize": "^0.6.9" + }, "peerDependencies": { "db-migrate": "^1.0.0-beta.21", "db-migrate-pg": "^1.3.0" diff --git a/services/feature-toggle-service/src/component.ts b/services/feature-toggle-service/src/component.ts index 30a523a142..eecc81f523 100644 --- a/services/feature-toggle-service/src/component.ts +++ b/services/feature-toggle-service/src/component.ts @@ -38,6 +38,11 @@ import { FeatureValuesRepository, StrategyRepository, } from './repositories'; +import { + FeatureRepository as FeatureSequelizeRepository, + FeatureValuesRepository as FeatureValuesSequelizeRepository, + StrategyRepository as StrategySequelizeRepository, +} from './repositories/sequelize'; import {IToggleServiceConfig} from './types'; export class FeatureToggleServiceComponent implements Component { @@ -70,11 +75,19 @@ export class FeatureToggleServiceComponent implements Component { // Mount default sequence if needed this.setupSequence(); } - this.repositories = [ - FeatureRepository, - FeatureValuesRepository, - StrategyRepository, - ]; + if (this.config?.useSequelize) { + this.repositories = [ + FeatureSequelizeRepository, + FeatureValuesSequelizeRepository, + StrategySequelizeRepository, + ]; + } else { + this.repositories = [ + FeatureRepository, + FeatureValuesRepository, + StrategyRepository, + ]; + } this.models = [Feature, FeatureValues, Strategy]; this.controllers = [ diff --git a/services/feature-toggle-service/src/repositories/sequelize/feature-values.repository.ts b/services/feature-toggle-service/src/repositories/sequelize/feature-values.repository.ts new file mode 100644 index 0000000000..ee5173429b --- /dev/null +++ b/services/feature-toggle-service/src/repositories/sequelize/feature-values.repository.ts @@ -0,0 +1,22 @@ +import {Getter, inject} from '@loopback/core'; +import {IAuthUserWithPermissions} from '@sourceloop/core'; +import {AuthenticationBindings} from 'loopback4-authentication'; +import {FeatureValues} from '../../models'; +import {FeatureToggleDbName} from '../../types'; +import {SequelizeSoftCrudRepository} from 'loopback4-soft-delete/sequelize'; +import {SequelizeDataSource} from '@loopback/sequelize'; +export class FeatureValuesRepository extends SequelizeSoftCrudRepository< + FeatureValues, + typeof FeatureValues.prototype.id +> { + constructor( + @inject(`datasources.${FeatureToggleDbName}`) + dataSource: SequelizeDataSource, + @inject.getter(AuthenticationBindings.CURRENT_USER) + protected readonly getCurrentUser: Getter< + IAuthUserWithPermissions | undefined + >, + ) { + super(FeatureValues, dataSource, getCurrentUser); + } +} diff --git a/services/feature-toggle-service/src/repositories/sequelize/feature.repository.ts b/services/feature-toggle-service/src/repositories/sequelize/feature.repository.ts new file mode 100644 index 0000000000..dd9b6b16a5 --- /dev/null +++ b/services/feature-toggle-service/src/repositories/sequelize/feature.repository.ts @@ -0,0 +1,27 @@ +// Copyright (c) 2023 Sourcefuse Technologies +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT +import {Getter, inject} from '@loopback/core'; +import {IAuthUserWithPermissions} from '@sourceloop/core'; +import {SequelizeSoftCrudRepository} from 'loopback4-soft-delete/sequelize'; +import {SequelizeDataSource} from '@loopback/sequelize'; +import {AuthenticationBindings} from 'loopback4-authentication'; +import {Feature} from '../../models'; +import {FeatureToggleDbName} from '../../types'; + +export class FeatureRepository extends SequelizeSoftCrudRepository< + Feature, + typeof Feature.prototype.name +> { + constructor( + @inject(`datasources.${FeatureToggleDbName}`) + dataSource: SequelizeDataSource, + @inject.getter(AuthenticationBindings.CURRENT_USER) + protected readonly getCurrentUser: Getter< + IAuthUserWithPermissions | undefined + >, + ) { + super(Feature, dataSource, getCurrentUser); + } +} diff --git a/services/feature-toggle-service/src/repositories/sequelize/index.ts b/services/feature-toggle-service/src/repositories/sequelize/index.ts new file mode 100644 index 0000000000..695c9a2a45 --- /dev/null +++ b/services/feature-toggle-service/src/repositories/sequelize/index.ts @@ -0,0 +1,7 @@ +// Copyright (c) 2023 Sourcefuse Technologies +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT +export * from './feature-values.repository'; +export * from './feature.repository'; +export * from './strategy.repository'; diff --git a/services/feature-toggle-service/src/repositories/sequelize/strategy.repository.ts b/services/feature-toggle-service/src/repositories/sequelize/strategy.repository.ts new file mode 100644 index 0000000000..6958e95cf7 --- /dev/null +++ b/services/feature-toggle-service/src/repositories/sequelize/strategy.repository.ts @@ -0,0 +1,27 @@ +// Copyright (c) 2023 Sourcefuse Technologies +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT +import {Getter, inject} from '@loopback/core'; +import {IAuthUserWithPermissions} from '@sourceloop/core'; +import {SequelizeSoftCrudRepository} from 'loopback4-soft-delete/sequelize'; +import {SequelizeDataSource} from '@loopback/sequelize'; +import {AuthenticationBindings} from 'loopback4-authentication'; +import {Strategy} from '../../models'; +import {FeatureToggleDbName} from '../../types'; + +export class StrategyRepository extends SequelizeSoftCrudRepository< + Strategy, + typeof Strategy.prototype.name +> { + constructor( + @inject(`datasources.${FeatureToggleDbName}`) + dataSource: SequelizeDataSource, + @inject.getter(AuthenticationBindings.CURRENT_USER) + protected readonly getCurrentUser: Getter< + IAuthUserWithPermissions | undefined + >, + ) { + super(Strategy, dataSource, getCurrentUser); + } +}