Skip to content

Commit cf7e47f

Browse files
rely entirely on model name and prisma service for service with improved extend support
1 parent 669b77a commit cf7e47f

File tree

2 files changed

+55
-47
lines changed

2 files changed

+55
-47
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@januscaler/tsed-helper",
3-
"version": "2.2.7",
3+
"version": "2.3.0",
44
"type": "module",
55
"publishConfig": {
66
"@januscaler:registry": "https://npm.pkg.github.com"

src/baseService.ts

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,63 @@ import { PrismaMapperEntity, PrismaMapperEntityField, PrismaMetaMapper } from '.
66
import { Generics } from '@tsed/schema';
77
import { SearchFilterRecord, SearchFilterValue } from './types.js';
88

9-
export interface IBaseService {
10-
onUpdate: Subject<{ id: number, inputData: any, result: any }>
11-
onDelete: Subject<{ id: number, result: any }>
12-
onCreate: Subject<{ data: any, result: any }>
9+
export interface IBaseService<M> {
10+
onPostUpdate: Subject<{ id: number, inputData: M, result: any }>
11+
onPreUpdate?: Subject<{ id: number, inputData: M }>
12+
onPreDelete?: Subject<{ id: number }>
13+
onPostDelete: Subject<{ id: number, result: any }>
14+
onPreCreate?: Subject<{ data: M }>
15+
onPostCreate: Subject<{ data: M, result: any }>
1316
}
14-
@Generics("T")
15-
export class BaseService<T> implements OnInit, IBaseService {
17+
18+
@Generics("T", "M")
19+
export class BaseService<T, M> implements OnInit, IBaseService<M> {
1620
/**
1721
* Service configuration options.
1822
*
19-
* @property {Prisma.Repository} injectedRepository - A valid Prisma model repository required for this service.
20-
* @property {PrismaService} prismaService - An instance of the PrismaService.
23+
* @property {string} tsedPrismaModelName - A valid Prisma model name required for this service.
24+
* @property {PrismaService} prismaService - An instance of the PrismaService used for computations and extensions.
2125
* @property {string} [relativePrismaFilePath="./prisma/schema.prisma"] - Optional path to the Prisma schema file. Defaults to "./prisma/schema.prisma".
2226
*/
23-
constructor(public injectedRepository: any, private prismaService: any, relativePrismaFilePath?: string) {
27+
constructor(public tsedPrismaModelName: any, private prismaService: any, relativePrismaFilePath?: string) {
2428
this.prismaFilePath = relativePrismaFilePath ?? "./prisma/schema.prisma"
2529
}
30+
2631
public prismaFilePath: string
2732
tablesInfo: Record<string, PrismaMapperEntity> = {}
2833

29-
onUpdate: Subject<{ id: number, inputData: any, result: any }> = new Subject()
30-
31-
onCreate: Subject<{ data: any, result: any }> = new Subject()
32-
33-
onDelete: Subject<{ id: number, result: any }> = new Subject()
34+
onPostUpdate: Subject<{ id: number, inputData: M, result: any }> = new Subject()
35+
onPreUpdate?: Subject<{ id: number; inputData: M; }> = new Subject()
36+
onPreDelete?: Subject<{ id: number }> = new Subject()
37+
onPreCreate?: Subject<{ data: M }> = new Subject();
38+
onPostCreate: Subject<{ data: M, result: any }> = new Subject()
39+
onPostDelete: Subject<{ id: number, result: any }> = new Subject()
3440

3541
get repository() {
36-
return this.injectedRepository as T;
42+
return this.prismaService[this.modelName] as T;
3743
}
3844

39-
get fieldNames() {
40-
if (this.injectedRepository?.collection) {
41-
return Object.keys(this.injectedRepository.collection.fields)
42-
}
43-
else if (this.injectedRepository?.fields) {
44-
return Object.keys(this.injectedRepository.fields)
45-
}
46-
throw new Error('injectedRepository has no fields, probably you passed wrong repository');
45+
get modelName() {
46+
return _.camelCase(_.split(this.tsedPrismaModelName, 'Model')[0]) as string;
4747
}
4848

49-
get currentModelName() {
50-
if (this.injectedRepository?.name) {
51-
return this.injectedRepository.name
49+
get fieldNames() {
50+
// @ts-ignore
51+
if ((this.repository as any)?.collection) {
52+
// @ts-ignore
53+
return Object.keys((this.repository as any).collection.fields)
5254
}
53-
if (this.injectedRepository?.collection?.name) {
54-
return this.injectedRepository.collection.name;
55+
// @ts-ignore
56+
else if ((this.repository as any)?.fields) {
57+
// @ts-ignore
58+
return Object.keys((this.repository as any).fields)
5559
}
60+
throw new Error('repository has no fields, probably you passed wrong repository');
5661
}
5762

63+
5864
get currentModelInfo() {
59-
return this.tablesInfo[this.currentModelName]
65+
return this.tablesInfo[this.modelName]
6066
}
6167

6268
get currentModelFieldsMapping() {
@@ -66,16 +72,15 @@ export class BaseService<T> implements OnInit, IBaseService {
6672
}, {}) as Record<string, PrismaMapperEntityField>
6773
}
6874

69-
extend<T>(model: string, computedFields: Record<string, {
70-
needs: Partial<Record<keyof T, boolean>>
71-
compute: (model: T) => any
75+
extend<M>(computedFields: Record<string, {
76+
needs: Partial<Record<keyof M, boolean>>
77+
compute: (model: M) => any
7278
}>) {
73-
const data = this.prismaService.$extends({
79+
this.prismaService.$extends({
7480
result: {
75-
[_.camelCase(model)]: computedFields as any
81+
[this.modelName]: computedFields as any
7682
}
7783
})
78-
this.injectedRepository = data[_.camelCase(model)]
7984
}
8085

8186

@@ -84,20 +89,22 @@ export class BaseService<T> implements OnInit, IBaseService {
8489
this.tablesInfo = await prismaMapper.getTablesInfo()
8590
}
8691

87-
async create(data: any) {
88-
const result = await this.injectedRepository.create({ data });
89-
this.onCreate.next({ data, result });
92+
async create(data: M) {
93+
this.onPreCreate?.next({ data });
94+
const result = await (this.repository as any).create({ data });
95+
this.onPostCreate.next({ data, result });
9096
return result;
9197
}
9298

9399
async deleteItem(id: number) {
94-
const result = await this.injectedRepository.delete({ where: { id }, select: { id: true } });
95-
this.onDelete.next({ id, result });
100+
this.onPreDelete?.next({ id });
101+
const result = await (this.repository as any).delete({ where: { id }, select: { id: true } });
102+
this.onPostDelete.next({ id, result });
96103
return result;
97104
}
98105

99106
async getOne(id: number) {
100-
return (await this.injectedRepository.findFirst({ where: { id } })) || {};
107+
return (await (this.repository as any).findFirst({ where: { id } })) || {};
101108
}
102109

103110
async update(id: number, data: any, { relationOperation, relationvalueMapper }: {
@@ -115,8 +122,9 @@ export class BaseService<T> implements OnInit, IBaseService {
115122
}, {
116123
...dataWithRelations
117124
})
118-
const result = await this.injectedRepository.update({ where: { id }, data: finalData });
119-
this.onUpdate.next({ id, inputData: data, result });
125+
this.onPreUpdate?.next({ id, inputData: data });
126+
const result = await (this.repository as any).update({ where: { id }, data: finalData });
127+
this.onPostUpdate.next({ id, inputData: data, result });
120128
return result;
121129
}
122130

@@ -249,7 +257,7 @@ export class BaseService<T> implements OnInit, IBaseService {
249257
_.set(prismaFilters, `${propertyName}.lte`, endValue);
250258
_.set(prismaFilters, `${propertyName}.gte`, startValue);
251259
}
252-
260+
253261
},
254262
}
255263

@@ -293,13 +301,13 @@ export class BaseService<T> implements OnInit, IBaseService {
293301
where: prismaWhere,
294302
select: selectFields
295303
};
296-
const { _count: { id: total } } = await this.injectedRepository.aggregate({
304+
const { _count: { id: total } } = await (this.repository as any).aggregate({
297305
where: prismaWhere,
298306
_count: {
299307
id: true,
300308
}
301309
});
302-
const items = await this.injectedRepository.findMany(properties);
310+
const items = await (this.repository as any).findMany(properties);
303311
return {
304312
total,
305313
items

0 commit comments

Comments
 (0)