Skip to content

Commit aaeb150

Browse files
Samarpan  BhattacharyaSamarpan  Bhattacharya
Samarpan Bhattacharya
authored and
Samarpan Bhattacharya
committed
feat(repository): add new method to provide user identifier for deletedbyid
BREAKING CHANGE: change approach for custom identifier for deletedbyid gh-0
1 parent 1b7be1c commit aaeb150

9 files changed

+176
-45
lines changed

.mocharc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"recursive": true,
3+
"reporter": ["dot"],
34
"require": "source-map-support/register"
45
}

README.md

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,12 @@ export class ItemRepository extends SoftCrudRepositoryMixin<
193193

194194
### deletedBy
195195

196-
Whenever any entry is deleted using deleteById, delete and deleteAll repository methods, it also sets deletedBy column with a value with user id whoever is logged in currently. Hence it uses a Getter function of IAuthUser type. However, if you want to use some other attribute of user model other than id, you can do it by overriding deletedByIdKey. Here is an example.
196+
Whenever any entry is deleted using deleteById, delete and deleteAll repository methods, it also sets deletedBy column with a value with user id whoever is logged in currently. Hence it uses a Getter function of IUser type. However, if you want to use some other attribute of user model other than id, you can do it by overriding deletedByIdKey. Here is an example.
197197

198198
```ts
199199
import {Getter, inject} from '@loopback/core';
200200
import {SoftCrudRepository, IUser} from 'loopback4-soft-delete';
201-
import {AuthenticationBindings, IAuthUser} from 'loopback4-authentication';
201+
import {AuthenticationBindings} from 'loopback4-authentication';
202202

203203
import {PgdbDataSource} from '../datasources';
204204
import {User, UserRelations} from '../models';
@@ -211,10 +211,32 @@ export class UserRepository extends SoftCrudRepository<
211211
constructor(
212212
@inject('datasources.pgdb') dataSource: PgdbDataSource,
213213
@inject.getter(AuthenticationBindings.CURRENT_USER, {optional: true})
214-
protected readonly getCurrentUser: Getter<(IAuthUser & IUser) | undefined>,
215-
protected readonly deletedByIdKey: string = 'userTenantId',
214+
protected readonly getCurrentUser: Getter<User | undefined>,
216215
) {
217-
super(User, dataSource, getCurrentUser, deletedByIdKey);
216+
super(User, dataSource, getCurrentUser);
217+
}
218+
}
219+
```
220+
221+
Model class for custom identifier case. Notice the `getIdentifier() method` and `IUser` interface implemented.
222+
223+
```ts
224+
@model()
225+
class User extends SoftDeleteEntity implements IUser {
226+
@property({
227+
id: true,
228+
})
229+
id: string;
230+
231+
@property()
232+
username: string;
233+
234+
getIdentifier() {
235+
return this.username;
236+
}
237+
238+
constructor(data?: Partial<User>) {
239+
super(data);
218240
}
219241
}
220242
```

src/__tests__/unit/mixin/soft-crud.mixin.unit.ts

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
Entity,
1313
EntityNotFoundError,
1414
juggler,
15+
Model,
1516
model,
1617
property,
1718
} from '@loopback/repository';
@@ -43,6 +44,40 @@ class Customer2 extends SoftDeleteEntity {
4344
email: string;
4445
}
4546

47+
@model()
48+
class User extends Model implements IUser {
49+
@property({
50+
id: true,
51+
})
52+
id: string;
53+
54+
@property()
55+
username: string;
56+
57+
constructor(data?: Partial<User>) {
58+
super(data);
59+
}
60+
}
61+
62+
@model()
63+
class UserWithCustomId extends Model implements IUser {
64+
@property({
65+
id: true,
66+
})
67+
id: string;
68+
69+
@property()
70+
username: string;
71+
72+
getIdentifier() {
73+
return this.username;
74+
}
75+
76+
constructor(data?: Partial<UserWithCustomId>) {
77+
super(data);
78+
}
79+
}
80+
4681
class CustomerCrudRepo extends SoftCrudRepositoryMixin<
4782
Customer,
4883
typeof Customer.prototype.id,
@@ -76,7 +111,6 @@ class Customer2CrudRepo extends SoftCrudRepositoryMixin<
76111
},
77112
dataSource: juggler.DataSource,
78113
readonly getCurrentUser: Getter<IUser | undefined>,
79-
readonly deletedByIdKey: string = 'id',
80114
) {
81115
super(entityClass, dataSource, getCurrentUser);
82116
}
@@ -85,22 +119,24 @@ class Customer2CrudRepo extends SoftCrudRepositoryMixin<
85119
describe('SoftCrudRepositoryMixin', () => {
86120
let repo: CustomerCrudRepo;
87121
let repoWithCustomDeletedByKey: Customer2CrudRepo;
88-
const userData = {
122+
const userData: User = new User({
89123
id: '1',
90124
username: 'test',
91-
};
125+
});
126+
127+
const userData2: UserWithCustomId = new UserWithCustomId({
128+
id: '2',
129+
username: 'test2',
130+
});
92131

93132
before(() => {
94133
const ds: juggler.DataSource = new juggler.DataSource({
95134
name: 'db',
96135
connector: 'memory',
97136
});
98137
repo = new CustomerCrudRepo(Customer, ds, () => Promise.resolve(userData));
99-
repoWithCustomDeletedByKey = new Customer2CrudRepo(
100-
Customer2,
101-
ds,
102-
() => Promise.resolve(userData),
103-
'username',
138+
repoWithCustomDeletedByKey = new Customer2CrudRepo(Customer2, ds, () =>
139+
Promise.resolve(userData2),
104140
);
105141
});
106142

@@ -587,7 +623,7 @@ describe('SoftCrudRepositoryMixin', () => {
587623
await repoWithCustomDeletedByKey.findByIdIncludeSoftDelete(1);
588624
expect(afterDeleteIncludeSoftDeleted)
589625
.to.have.property('deletedBy')
590-
.equal(userData.username);
626+
.equal(userData2.username);
591627
});
592628
});
593629

@@ -639,7 +675,7 @@ describe('SoftCrudRepositoryMixin', () => {
639675
await repoWithCustomDeletedByKey.findByIdIncludeSoftDelete(1);
640676
expect(afterDeleteIncludeSoftDeleted)
641677
.to.have.property('deletedBy')
642-
.equal(userData.username);
678+
.equal(userData2.username);
643679
});
644680
});
645681

@@ -673,7 +709,7 @@ describe('SoftCrudRepositoryMixin', () => {
673709
const afterDeleteAll = await repoWithCustomDeletedByKey.findAll();
674710
expect(afterDeleteAll).to.have.length(4);
675711
afterDeleteAll.forEach((rec) => {
676-
expect(rec).to.have.property('deletedBy').equal(userData.username);
712+
expect(rec).to.have.property('deletedBy').equal(userData2.username);
677713
});
678714
});
679715
});

src/__tests__/unit/repository/default-transaction-soft-crud.repository.base.ts

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
Entity,
1111
EntityNotFoundError,
1212
juggler,
13+
Model,
1314
model,
1415
property,
1516
} from '@loopback/repository';
@@ -41,6 +42,40 @@ class Customer2 extends SoftDeleteEntity {
4142
email: string;
4243
}
4344

45+
@model()
46+
class User extends Model implements IUser {
47+
@property({
48+
id: true,
49+
})
50+
id: string;
51+
52+
@property()
53+
username: string;
54+
55+
constructor(data?: Partial<User>) {
56+
super(data);
57+
}
58+
}
59+
60+
@model()
61+
class UserWithCustomId extends Model implements IUser {
62+
@property({
63+
id: true,
64+
})
65+
id: string;
66+
67+
@property()
68+
username: string;
69+
70+
getIdentifier() {
71+
return this.username;
72+
}
73+
74+
constructor(data?: Partial<UserWithCustomId>) {
75+
super(data);
76+
}
77+
}
78+
4479
class CustomerCrudRepo extends DefaultTransactionSoftCrudRepository<
4580
Customer,
4681
number
@@ -66,7 +101,6 @@ class Customer2CrudRepo extends DefaultTransactionSoftCrudRepository<
66101
},
67102
dataSource: juggler.DataSource,
68103
protected readonly getCurrentUser?: Getter<IUser | undefined>,
69-
protected readonly deletedByIdKey: string = 'id',
70104
) {
71105
super(entityClass, dataSource, getCurrentUser);
72106
}
@@ -75,22 +109,24 @@ class Customer2CrudRepo extends DefaultTransactionSoftCrudRepository<
75109
describe('DefaultTransactionSoftCrudRepository', () => {
76110
let repo: CustomerCrudRepo;
77111
let repoWithCustomDeletedByKey: Customer2CrudRepo;
78-
const userData = {
112+
const userData: User = new User({
79113
id: '1',
80114
username: 'test',
81-
};
115+
});
116+
117+
const userData2: UserWithCustomId = new UserWithCustomId({
118+
id: '2',
119+
username: 'test2',
120+
});
82121

83122
before(() => {
84123
const ds: juggler.DataSource = new juggler.DataSource({
85124
name: 'db',
86125
connector: 'memory',
87126
});
88127
repo = new CustomerCrudRepo(Customer, ds, () => Promise.resolve(userData));
89-
repoWithCustomDeletedByKey = new Customer2CrudRepo(
90-
Customer2,
91-
ds,
92-
() => Promise.resolve(userData),
93-
'username',
128+
repoWithCustomDeletedByKey = new Customer2CrudRepo(Customer2, ds, () =>
129+
Promise.resolve(userData2),
94130
);
95131
});
96132

@@ -577,7 +613,7 @@ describe('DefaultTransactionSoftCrudRepository', () => {
577613
await repoWithCustomDeletedByKey.findByIdIncludeSoftDelete(1);
578614
expect(afterDeleteIncludeSoftDeleted)
579615
.to.have.property('deletedBy')
580-
.equal(userData.username);
616+
.equal(userData2.username);
581617
});
582618
});
583619

@@ -630,7 +666,7 @@ describe('DefaultTransactionSoftCrudRepository', () => {
630666
await repoWithCustomDeletedByKey.findByIdIncludeSoftDelete(1);
631667
expect(afterDeleteIncludeSoftDeleted)
632668
.to.have.property('deletedBy')
633-
.equal(userData.username);
669+
.equal(userData2.username);
634670
});
635671
});
636672

@@ -664,7 +700,7 @@ describe('DefaultTransactionSoftCrudRepository', () => {
664700
const afterDeleteAll = await repoWithCustomDeletedByKey.findAll();
665701
expect(afterDeleteAll).to.have.length(4);
666702
afterDeleteAll.forEach((rec) => {
667-
expect(rec).to.have.property('deletedBy').equal(userData.username);
703+
expect(rec).to.have.property('deletedBy').equal(userData2.username);
668704
});
669705
});
670706
});

0 commit comments

Comments
 (0)