Skip to content

Commit 9899d1a

Browse files
feat(feature-toggle): add sequelize ORM
GH-2240
1 parent 0c9e42e commit 9899d1a

File tree

7 files changed

+119
-5
lines changed

7 files changed

+119
-5
lines changed

services/feature-toggle-service/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,21 @@ npm i @sourceloop/feature-toggle-service
4949
- Start the application
5050
`npm start`
5151

52+
### Using with Sequelize
53+
54+
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.
55+
56+
1. To use Sequelize in your application, add following to application.ts:
57+
58+
```ts
59+
this.bind(FeatureToggleBindings.Config).to({
60+
bindControllers: true,
61+
useCustomSequence: false,
62+
});
63+
```
64+
65+
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.
66+
5267
### Asymmetric Token Signing and Verification
5368

5469
If you are using asymmetric token signing and verification, you need to create a datasource for auth database. Example datasource file for auth:-

services/feature-toggle-service/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@
9696
"typescript": "^5.4.5",
9797
"widdershins": "^4.0.1"
9898
},
99+
"optionalDependencies": {
100+
"@loopback/sequelize": "^0.6.9"
101+
},
99102
"peerDependencies": {
100103
"db-migrate": "^1.0.0-beta.21",
101104
"db-migrate-pg": "^1.3.0"

services/feature-toggle-service/src/component.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ import {
3838
FeatureValuesRepository,
3939
StrategyRepository,
4040
} from './repositories';
41+
import {
42+
FeatureRepository as FeatureSequelizeRepository,
43+
FeatureValuesRepository as FeatureValuesSequelizeRepository,
44+
StrategyRepository as StrategySequelizeRepository,
45+
} from './repositories/sequelize';
4146
import {IToggleServiceConfig} from './types';
4247

4348
export class FeatureToggleServiceComponent implements Component {
@@ -70,11 +75,19 @@ export class FeatureToggleServiceComponent implements Component {
7075
// Mount default sequence if needed
7176
this.setupSequence();
7277
}
73-
this.repositories = [
74-
FeatureRepository,
75-
FeatureValuesRepository,
76-
StrategyRepository,
77-
];
78+
if (this.config?.useSequelize) {
79+
this.repositories = [
80+
FeatureSequelizeRepository,
81+
FeatureValuesSequelizeRepository,
82+
StrategySequelizeRepository,
83+
];
84+
} else {
85+
this.repositories = [
86+
FeatureRepository,
87+
FeatureValuesRepository,
88+
StrategyRepository,
89+
];
90+
}
7891
this.models = [Feature, FeatureValues, Strategy];
7992

8093
this.controllers = [
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import {Getter, inject} from '@loopback/core';
2+
import {IAuthUserWithPermissions} from '@sourceloop/core';
3+
import {AuthenticationBindings} from 'loopback4-authentication';
4+
import {FeatureValues} from '../../models';
5+
import {FeatureToggleDbName} from '../../types';
6+
import {SequelizeSoftCrudRepository} from 'loopback4-soft-delete/sequelize';
7+
import {SequelizeDataSource} from '@loopback/sequelize';
8+
export class FeatureValuesRepository extends SequelizeSoftCrudRepository<
9+
FeatureValues,
10+
typeof FeatureValues.prototype.id
11+
> {
12+
constructor(
13+
@inject(`datasources.${FeatureToggleDbName}`)
14+
dataSource: SequelizeDataSource,
15+
@inject.getter(AuthenticationBindings.CURRENT_USER)
16+
protected readonly getCurrentUser: Getter<
17+
IAuthUserWithPermissions | undefined
18+
>,
19+
) {
20+
super(FeatureValues, dataSource, getCurrentUser);
21+
}
22+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) 2023 Sourcefuse Technologies
2+
//
3+
// This software is released under the MIT License.
4+
// https://opensource.org/licenses/MIT
5+
import {Getter, inject} from '@loopback/core';
6+
import {IAuthUserWithPermissions} from '@sourceloop/core';
7+
import {SequelizeSoftCrudRepository} from 'loopback4-soft-delete/sequelize';
8+
import {SequelizeDataSource} from '@loopback/sequelize';
9+
import {AuthenticationBindings} from 'loopback4-authentication';
10+
import {Feature} from '../../models';
11+
import {FeatureToggleDbName} from '../../types';
12+
13+
export class FeatureRepository extends SequelizeSoftCrudRepository<
14+
Feature,
15+
typeof Feature.prototype.name
16+
> {
17+
constructor(
18+
@inject(`datasources.${FeatureToggleDbName}`)
19+
dataSource: SequelizeDataSource,
20+
@inject.getter(AuthenticationBindings.CURRENT_USER)
21+
protected readonly getCurrentUser: Getter<
22+
IAuthUserWithPermissions | undefined
23+
>,
24+
) {
25+
super(Feature, dataSource, getCurrentUser);
26+
}
27+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (c) 2023 Sourcefuse Technologies
2+
//
3+
// This software is released under the MIT License.
4+
// https://opensource.org/licenses/MIT
5+
export * from './feature-values.repository';
6+
export * from './feature.repository';
7+
export * from './strategy.repository';
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) 2023 Sourcefuse Technologies
2+
//
3+
// This software is released under the MIT License.
4+
// https://opensource.org/licenses/MIT
5+
import {Getter, inject} from '@loopback/core';
6+
import {IAuthUserWithPermissions} from '@sourceloop/core';
7+
import {SequelizeSoftCrudRepository} from 'loopback4-soft-delete/sequelize';
8+
import {SequelizeDataSource} from '@loopback/sequelize';
9+
import {AuthenticationBindings} from 'loopback4-authentication';
10+
import {Strategy} from '../../models';
11+
import {FeatureToggleDbName} from '../../types';
12+
13+
export class StrategyRepository extends SequelizeSoftCrudRepository<
14+
Strategy,
15+
typeof Strategy.prototype.name
16+
> {
17+
constructor(
18+
@inject(`datasources.${FeatureToggleDbName}`)
19+
dataSource: SequelizeDataSource,
20+
@inject.getter(AuthenticationBindings.CURRENT_USER)
21+
protected readonly getCurrentUser: Getter<
22+
IAuthUserWithPermissions | undefined
23+
>,
24+
) {
25+
super(Strategy, dataSource, getCurrentUser);
26+
}
27+
}

0 commit comments

Comments
 (0)