@drax/crud-back 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/controllers/AbstractFastifyController.js +193 -0
  2. package/dist/index.js +8 -0
  3. package/dist/interfaces/ICrudRepository.js +1 -0
  4. package/dist/interfaces/IEntityPermission.js +1 -0
  5. package/dist/interfaces/IEntityRepository.js +1 -0
  6. package/dist/repository/AbstractMongoRepository.js +87 -0
  7. package/dist/repository/AbstractSqliteRepository.js +121 -0
  8. package/dist/services/AbstractService.js +122 -0
  9. package/package.json +45 -0
  10. package/src/controllers/AbstractFastifyController.ts +209 -0
  11. package/src/index.ts +19 -0
  12. package/src/interfaces/ICrudRepository.ts +16 -0
  13. package/src/interfaces/IEntityPermission.ts +10 -0
  14. package/src/repository/AbstractMongoRepository.ts +118 -0
  15. package/src/repository/AbstractSqliteRepository.ts +170 -0
  16. package/src/services/AbstractService.ts +145 -0
  17. package/tsconfig.json +16 -0
  18. package/tsconfig.tsbuildinfo +1 -0
  19. package/types/controllers/AbstractFastifyController.d.ts +37 -0
  20. package/types/controllers/AbstractFastifyController.d.ts.map +1 -0
  21. package/types/index.d.ts +8 -0
  22. package/types/index.d.ts.map +1 -0
  23. package/types/interfaces/ICrudRepository.d.ts +15 -0
  24. package/types/interfaces/ICrudRepository.d.ts.map +1 -0
  25. package/types/interfaces/IEntityPermission.d.ts +10 -0
  26. package/types/interfaces/IEntityPermission.d.ts.map +1 -0
  27. package/types/interfaces/IEntityRepository.d.ts +5 -0
  28. package/types/interfaces/IEntityRepository.d.ts.map +1 -0
  29. package/types/repository/AbstractMongoRepository.d.ts +23 -0
  30. package/types/repository/AbstractMongoRepository.d.ts.map +1 -0
  31. package/types/repository/AbstractSqliteRepository.d.ts +24 -0
  32. package/types/repository/AbstractSqliteRepository.d.ts.map +1 -0
  33. package/types/services/AbstractService.d.ts +21 -0
  34. package/types/services/AbstractService.d.ts.map +1 -0
@@ -0,0 +1,209 @@
1
+ import AbstractService from "../services/AbstractService";
2
+ import {ValidationError} from "@drax/common-back";
3
+ import {UnauthorizedError, Rbac} from "@drax/identity-back";
4
+ import type {FastifyReply, FastifyRequest} from "fastify";
5
+ import {IEntityPermission} from "../interfaces/IEntityPermission";
6
+
7
+ declare module 'fastify' {
8
+ interface FastifyRequest {
9
+ rbac?: Rbac;
10
+ }
11
+ }
12
+
13
+ type CustomRequest = FastifyRequest<{
14
+ Params: {
15
+ id?: string
16
+ ids?: string
17
+ };
18
+ Querystring:{
19
+ page?: number
20
+ limit?: number
21
+ orderBy?: string
22
+ order?: 'asc' | 'desc' | boolean
23
+ search?: string
24
+ }
25
+ }>
26
+
27
+ class AbstractFastifyController<T,C,U>{
28
+
29
+ protected service: AbstractService<T,C,U>
30
+ protected permission: IEntityPermission
31
+
32
+ constructor(service: AbstractService<T, C, U>, permission: IEntityPermission) {
33
+ this.service = service
34
+ this.permission = permission
35
+ console.log("AbstractFastifyController created. Permissions", this.permission)
36
+ }
37
+
38
+
39
+ async findById(request:CustomRequest, reply: FastifyReply) {
40
+ try {
41
+ request.rbac.assertPermission(this.permission.View)
42
+ if(!request.params.id){
43
+ reply.statusCode = 400
44
+ reply.send({error: 'BAD REQUEST'})
45
+ }
46
+ const id = request.params.id
47
+ let item = await this.service.findById(id)
48
+ return item
49
+ } catch (e) {
50
+ console.error(e)
51
+ if (e instanceof ValidationError) {
52
+ reply.statusCode = e.statusCode
53
+ reply.send({error: e.message, inputErrors: e.errors})
54
+ } else if (e instanceof UnauthorizedError) {
55
+ reply.statusCode = e.statusCode
56
+ reply.send({error: e.message})
57
+ } else {
58
+ reply.statusCode = 500
59
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
60
+ }
61
+ }
62
+ }
63
+
64
+ async findByIds(request:CustomRequest, reply: FastifyReply) {
65
+ try {
66
+ request.rbac.assertPermission(this.permission.View)
67
+ if(!request.params.ids){
68
+ reply.statusCode = 400
69
+ reply.send({error: 'BAD REQUEST'})
70
+ }
71
+ const ids = request.params.ids.split(",")
72
+ let items = await this.service.findByIds(ids)
73
+ return items
74
+ } catch (e) {
75
+ console.error(e)
76
+ if (e instanceof ValidationError) {
77
+ reply.statusCode = e.statusCode
78
+ reply.send({error: e.message, inputErrors: e.errors})
79
+ } else if (e instanceof UnauthorizedError) {
80
+ reply.statusCode = e.statusCode
81
+ reply.send({error: e.message})
82
+ } else {
83
+ reply.statusCode = 500
84
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
85
+ }
86
+ }
87
+ }
88
+
89
+ async search(request:CustomRequest, reply: FastifyReply) {
90
+ try {
91
+ request.rbac.assertPermission(this.permission.View)
92
+ const search = request.query.search
93
+ let item = await this.service.search(search)
94
+ return item
95
+ } catch (e) {
96
+ console.error(e)
97
+ if (e instanceof ValidationError) {
98
+ reply.statusCode = e.statusCode
99
+ reply.send({error: e.message, inputErrors: e.errors})
100
+ } else if (e instanceof UnauthorizedError) {
101
+ reply.statusCode = e.statusCode
102
+ reply.send({error: e.message})
103
+ } else {
104
+ reply.statusCode = 500
105
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
106
+ }
107
+ }
108
+ }
109
+
110
+ async paginate(request: CustomRequest, reply: FastifyReply) {
111
+ try {
112
+ request.rbac.assertPermission(this.permission.View)
113
+ const page = request.query.page
114
+ const limit = request.query.limit
115
+ const orderBy = request.query.orderBy
116
+ const order = request.query.order
117
+ const search = request.query.search
118
+ let paginateResult = await this.service.paginate({page, limit, orderBy, order, search})
119
+ return paginateResult
120
+ } catch (e) {
121
+ console.error(e)
122
+ if (e instanceof ValidationError) {
123
+ reply.statusCode = e.statusCode
124
+ reply.send({error: e.message, inputErrors: e.errors})
125
+ } else if (e instanceof UnauthorizedError) {
126
+ reply.statusCode = e.statusCode
127
+ reply.send({error: e.message})
128
+ } else {
129
+ reply.statusCode = 500
130
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
131
+ }
132
+ }
133
+ }
134
+
135
+ async create(request: CustomRequest, reply: FastifyReply) {
136
+ try {
137
+ request.rbac.assertPermission(this.permission.Create)
138
+ const payload = request.body
139
+ let item = await this.service.create(payload as C)
140
+ return item
141
+ } catch (e) {
142
+ console.error(e)
143
+ if (e instanceof ValidationError) {
144
+ reply.statusCode = e.statusCode
145
+ reply.send({error: e.message, inputErrors: e.errors})
146
+ } else if (e instanceof UnauthorizedError) {
147
+ reply.statusCode = e.statusCode
148
+ reply.send({error: e.message})
149
+ } else {
150
+ reply.statusCode = 500
151
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
152
+ }
153
+ }
154
+ }
155
+
156
+ async update(request: CustomRequest, reply: FastifyReply) {
157
+ try {
158
+ request.rbac.assertPermission(this.permission.Update)
159
+ if(!request.params.id){
160
+ reply.statusCode = 400
161
+ reply.send({error: 'BAD REQUEST'})
162
+ }
163
+ const id = request.params.id
164
+ const payload = request.body
165
+ let item = await this.service.update(id, payload as U)
166
+ return item
167
+ } catch (e) {
168
+ console.error(e)
169
+ if (e instanceof ValidationError) {
170
+ reply.statusCode = e.statusCode
171
+ reply.send({error: e.message, inputErrors: e.errors})
172
+ } else if (e instanceof UnauthorizedError) {
173
+ reply.statusCode = e.statusCode
174
+ reply.send({error: e.message})
175
+ } else {
176
+ reply.statusCode = 500
177
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
178
+ }
179
+ }
180
+ }
181
+
182
+ async delete(request: CustomRequest, reply: FastifyReply) {
183
+ try {
184
+ request.rbac.assertPermission(this.permission.Delete)
185
+ if(!request.params.id){
186
+ reply.statusCode = 400
187
+ reply.send({error: 'BAD REQUEST'})
188
+ }
189
+ const id = request.params.id
190
+ await this.service.delete(id)
191
+ reply.send({message: 'Item deleted successfully'})
192
+ } catch (e) {
193
+ console.error(e)
194
+ if (e instanceof ValidationError) {
195
+ reply.statusCode = e.statusCode
196
+ reply.send({error: e.message, inputErrors: e.errors})
197
+ } else if (e instanceof UnauthorizedError) {
198
+ reply.statusCode = e.statusCode
199
+ reply.send({error: e.message})
200
+ } else {
201
+ reply.statusCode = 500
202
+ reply.send({error: 'INTERNAL_SERVER_ERROR'})
203
+ }
204
+ }
205
+ }
206
+ }
207
+
208
+ export default AbstractFastifyController;
209
+ export {AbstractFastifyController}
package/src/index.ts ADDED
@@ -0,0 +1,19 @@
1
+ //CRUD
2
+ import AbstractMongoRepository from "./repository/AbstractMongoRepository.js";
3
+ import AbstractSqliteRepository from "./repository/AbstractSqliteRepository.js";
4
+ import AbstractService from "./services/AbstractService.js";
5
+ import AbstractFastifyController from "./controllers/AbstractFastifyController.js";
6
+
7
+ import type {ICrudRepository} from "./interfaces/ICrudRepository";
8
+
9
+ export type {ICrudRepository}
10
+
11
+ export {
12
+
13
+ //CRUD
14
+ AbstractMongoRepository,
15
+ AbstractSqliteRepository,
16
+ AbstractService,
17
+ AbstractFastifyController,
18
+
19
+ }
@@ -0,0 +1,16 @@
1
+ import type {IDraxPaginateOptions, IDraxPaginateResult} from "@drax/common-share";
2
+
3
+ interface ICrudRepository<T,C,U>{
4
+ paginate(options: IDraxPaginateOptions): Promise<IDraxPaginateResult<T>>
5
+ create(input: C): Promise<T>
6
+ update(id: string, input: U): Promise<T>
7
+ delete(id: string): Promise<any>
8
+
9
+ findById?(id: string): Promise<T | null>
10
+ findByIds?(ids: Array<string>): Promise<T[]>
11
+ findOneBy?(field: string, value: any): Promise<T | null>
12
+ findBy?(field: string, value: any): Promise<T[]>
13
+ fetchAll?(): Promise<T[]>
14
+ search?(value: any, limit ?: number): Promise<T[]>
15
+ }
16
+ export type { ICrudRepository }
@@ -0,0 +1,10 @@
1
+ interface IEntityPermission {
2
+ Create: string
3
+ Update: string
4
+ Delete: string
5
+ View: string
6
+ Manage: string
7
+ [key: string]: string
8
+ }
9
+
10
+ export type { IEntityPermission }
@@ -0,0 +1,118 @@
1
+ import "mongoose-paginate-v2";
2
+ import mongoose from "mongoose";
3
+ import {MongooseQueryFilter, MongooseSort, MongooseErrorToValidationError} from "@drax/common-back";
4
+ import type {DeleteResult} from "mongodb";
5
+ import type {IDraxPaginateOptions, IDraxPaginateResult} from "@drax/common-share";
6
+ import type {PaginateModel, PaginateOptions, PaginateResult} from "mongoose";
7
+ import type {ICrudRepository} from "../interfaces/ICrudRepository";
8
+
9
+
10
+
11
+ class AbstractMongoRepository<T,C,U> implements ICrudRepository<T,C,U> {
12
+
13
+ _model: mongoose.Model<T> & PaginateModel<T>
14
+ _searchFields: string[] = []
15
+ _populateFields: string[] = []
16
+
17
+
18
+ async create(data: C): Promise<T> {
19
+ try {
20
+ const item: mongoose.HydratedDocument<T> = new this._model(data)
21
+ await item.save()
22
+
23
+ //@ts-ignore
24
+ await item.populate(this._populateFields)
25
+
26
+ return item
27
+ } catch (e) {
28
+ if (e instanceof mongoose.Error.ValidationError) {
29
+ throw MongooseErrorToValidationError(e)
30
+ }
31
+ throw e
32
+ }
33
+ }
34
+
35
+ async update(id: string, data: U): Promise<T> {
36
+ try {
37
+ const item: mongoose.HydratedDocument<T> = await this._model.findOneAndUpdate({_id: id}, data, {new: true}).populate(this._populateFields).exec()
38
+ return item
39
+ } catch (e) {
40
+ if (e instanceof mongoose.Error.ValidationError) {
41
+ throw MongooseErrorToValidationError(e)
42
+ }
43
+ throw e
44
+ }
45
+ }
46
+
47
+ async delete(id: string): Promise<boolean> {
48
+ const result: DeleteResult = await this._model.deleteOne({_id: id}).exec()
49
+ return result.deletedCount == 1
50
+ }
51
+
52
+ async findById(id: string): Promise<T | null> {
53
+ const item: mongoose.HydratedDocument<T> | null = await this._model.findById(id).populate(this._populateFields).exec()
54
+ return item
55
+ }
56
+
57
+ async findByIds(ids: Array<string>): Promise<T[]> {
58
+ const items: mongoose.HydratedDocument<T>[] = await this._model.find({_id: {$in: ids}}).populate(this._populateFields).exec()
59
+ return items
60
+ }
61
+
62
+ async findOneBy(field: string, value: any): Promise<T | null> {
63
+ const filter: any = {[field]: value}
64
+ const item: mongoose.HydratedDocument<T> | null = await this._model.findOne(filter).populate(this._populateFields).exec()
65
+ return item
66
+ }
67
+
68
+ async findBy(field: string, value: any): Promise<T[]> {
69
+ const filter: any = {[field]: value}
70
+ const items: mongoose.HydratedDocument<T>[] = await this._model.find(filter).populate(this._populateFields).exec()
71
+ return items
72
+ }
73
+
74
+ async fetchAll(): Promise<T[]> {
75
+ const items: mongoose.HydratedDocument<T>[] = await this._model.find().populate(this._populateFields).exec()
76
+ return items
77
+ }
78
+
79
+ async search(value: string, limit : number = 1000): Promise<T[]> {
80
+ const query = {}
81
+ query['$or'] = this._searchFields.map(field => ({[field]: new RegExp(value, 'i')}))
82
+ const items: mongoose.HydratedDocument<T>[] = await this._model.find(query).limit(limit).exec()
83
+ return items
84
+ }
85
+
86
+
87
+ async paginate({
88
+ page = 1,
89
+ limit = 5,
90
+ orderBy = '',
91
+ order = false,
92
+ search = '',
93
+ filters = []
94
+ }: IDraxPaginateOptions): Promise<IDraxPaginateResult<T>> {
95
+
96
+ const query = {}
97
+
98
+ if (search) {
99
+ query['$or'] = this._searchFields.map(field => ({[field]: new RegExp(search, 'i')}))
100
+ }
101
+
102
+ MongooseQueryFilter.applyFilters(query, filters)
103
+
104
+ const sort = MongooseSort.applySort(orderBy, order)
105
+ const populate = this._populateFields
106
+ const options = {page, limit, sort, populate} as PaginateOptions
107
+ const items: PaginateResult<T> = await this._model.paginate(query, options)
108
+ return {
109
+ page: page,
110
+ limit: limit,
111
+ total: items.totalDocs,
112
+ items: items.docs
113
+ }
114
+ }
115
+ }
116
+
117
+ export default AbstractMongoRepository
118
+ export {AbstractMongoRepository}
@@ -0,0 +1,170 @@
1
+ import sqlite from "better-sqlite3";
2
+ import type {IDraxPaginateOptions, IDraxPaginateResult} from "@drax/common-share";
3
+ import {randomUUID} from "node:crypto";
4
+ import {
5
+ SqlSort, SqlQueryFilter, SqliteTableBuilder, SqliteTableField,
6
+ SqliteErrorToValidationError} from "@drax/common-back";
7
+
8
+
9
+
10
+ class AbstractSqliteRepository<T>{
11
+ protected db: any;
12
+ protected tableName: string;
13
+ protected dataBase: string;
14
+ protected searchFields: string[] = [];
15
+ protected booleanFields: string[] = [];
16
+ protected identifier: string = 'id';
17
+ protected verbose: boolean;
18
+ protected tableFields: SqliteTableField[];
19
+
20
+ constructor(dataBase:string, tableName: string, identifier:string = 'id',searchFields:string[] = [], booleanFields:string[] = [], verbose:boolean = false) {
21
+ if(!dataBase){
22
+ throw new Error("dataBase is required")
23
+ }
24
+
25
+ if(!tableName){
26
+ throw new Error("tableName is required")
27
+ }
28
+
29
+
30
+ this.dataBase = dataBase;
31
+ this.tableName = tableName
32
+ this.identifier = identifier
33
+ this.searchFields = searchFields
34
+ this.booleanFields = booleanFields
35
+ this.verbose = verbose;
36
+ this.db = new sqlite(dataBase, {verbose: verbose ? console.log : null});
37
+ }
38
+
39
+ build() {
40
+ const builder = new SqliteTableBuilder(this.dataBase, this.tableName, this.tableFields, this.verbose);
41
+ builder.build(this.identifier)
42
+ }
43
+
44
+ async create(data: any): Promise<T> {
45
+ try{
46
+
47
+ if(!data[this.identifier]){
48
+ data[this.identifier] = randomUUID()
49
+ }
50
+
51
+ for(const key in data){
52
+ if(typeof data[key] === 'boolean'){
53
+ data[key] = data[key]? 1 : 0
54
+ }
55
+ }
56
+
57
+ const fields = Object.keys(data)
58
+ .map(field => `${field}`)
59
+ .join(', ');
60
+
61
+ const values = Object.keys(data)
62
+ .map(field => `@${field}`)
63
+ .join(', ');
64
+
65
+ const stmt = this.db.prepare(`INSERT INTO ${this.tableName} (${fields}) VALUES (${values})`);
66
+ stmt.run(data)
67
+ return this.findById(data[this.identifier])
68
+ }catch (e){
69
+ console.log(e)
70
+ throw SqliteErrorToValidationError(e, data)
71
+ }
72
+ }
73
+
74
+ async findById(id: string): Promise<T | null>{
75
+ const item = this.db.prepare(`SELECT * FROM ${this.tableName} WHERE ${this.identifier} = ?`).get(id);
76
+ return item
77
+ }
78
+
79
+ async findBy(field: string, value: any): Promise<T[] | null>{
80
+ const item = this.db.prepare(`SELECT * FROM ${this.tableName} WHERE ${field} = ?`).all(value);
81
+ return item
82
+ }
83
+
84
+ async findOneBy(field: string, value: any): Promise<T | null>{
85
+ const item = this.db.prepare(`SELECT * FROM ${this.tableName} WHERE ${field} = ?`).get(value);
86
+ return item
87
+ }
88
+
89
+ async update(id: string, data: any): Promise<T> {
90
+ try{
91
+
92
+ for(const key in data){
93
+ if(typeof data[key] === 'boolean'){
94
+ data[key] = data[key]? 1 : 0
95
+ }
96
+ }
97
+
98
+ const setClauses = Object.keys(data)
99
+ .map(field => `${field} = @${field}`)
100
+ .join(', ');
101
+ data.identifier = id
102
+ const stmt = this.db.prepare( `UPDATE ${this.tableName} SET ${setClauses} WHERE ${this.identifier} = @identifier `);
103
+ stmt.run(data);
104
+ return this.findById(id)
105
+ }catch (e){
106
+ console.log(e)
107
+ throw SqliteErrorToValidationError(e, data)
108
+ }
109
+
110
+ }
111
+
112
+
113
+ async delete(id: string): Promise<boolean> {
114
+ const stmt = this.db.prepare(`DELETE FROM ${this.tableName} WHERE ${this.identifier} = ?`);
115
+ stmt.run(id);
116
+ return true
117
+ }
118
+
119
+
120
+
121
+ async paginate({
122
+ page= 1,
123
+ limit= 5,
124
+ orderBy= '',
125
+ order= 'desc',
126
+ search= '',
127
+ filters= []} : IDraxPaginateOptions): Promise<IDraxPaginateResult<T>>{
128
+
129
+ const offset = page > 1 ? (page - 1) * limit : 0
130
+
131
+ let where=""
132
+ if (search && this.searchFields.length > 0) {
133
+ where = ` WHERE ${this.searchFields.map(field => `${field} LIKE '%${search}%'`).join(" OR ")}`
134
+ }
135
+
136
+ if (filters.length > 0) {
137
+ where = SqlQueryFilter.applyFilters(where, filters)
138
+ }
139
+
140
+ const sort = SqlSort.applySort(orderBy, order)
141
+
142
+ const rCount = this.db.prepare(`SELECT COUNT(*) as count FROM ${this.tableName} ${where}`).get();
143
+ const items = this.db.prepare(`SELECT * FROM ${this.tableName} ${where} ${sort} LIMIT ? OFFSET ? `).all([limit, offset]) as T[];
144
+
145
+ for(const item of items){
146
+ for(const key in item) {
147
+ if (this.booleanFields.includes(key)) {
148
+ //@ts-ignore
149
+ item[key] = item[key] ? true : false
150
+ }
151
+ }
152
+ }
153
+
154
+ return {
155
+ page: page,
156
+ limit: limit,
157
+ total: rCount.count,
158
+ items: items
159
+ }
160
+ }
161
+
162
+ async fetchAll(): Promise<any[]>{
163
+ const tenants = this.db.prepare(`SELECT * FROM ${this.tableName}`).all();
164
+
165
+ return tenants
166
+ }
167
+
168
+ }
169
+
170
+ export default AbstractSqliteRepository
@@ -0,0 +1,145 @@
1
+ import {ValidationError, ZodErrorToValidationError} from "@drax/common-back"
2
+ import {ZodError} from "zod";
3
+ import type {ZodSchema} from "zod";
4
+ import type {IDraxPaginateOptions, IDraxPaginateResult} from "@drax/common-share";
5
+ import type {ICrudRepository} from "../interfaces/ICrudRepository";
6
+
7
+ class AbstractService<T,C,U> {
8
+
9
+ _repository: ICrudRepository<T,C,U>
10
+ _schema?: ZodSchema | undefined
11
+
12
+ constructor(repository: ICrudRepository<T,C,U>, schema?: ZodSchema) {
13
+ this._repository = repository
14
+ this._schema = schema
15
+ }
16
+
17
+ async create(data: C): Promise<T> {
18
+ try {
19
+ if(this._schema){
20
+ await this._schema.parseAsync(data)
21
+ }
22
+ const item: T = await this._repository.create(data)
23
+ return item
24
+ } catch (e) {
25
+ console.error("Error creating", e)
26
+ if (e instanceof ZodError) {
27
+ throw ZodErrorToValidationError(e, data)
28
+ }
29
+ throw e
30
+ }
31
+ }
32
+
33
+ async update(id: string, data: U): Promise<T> {
34
+ try {
35
+ if(this._schema){
36
+ await this._schema.parseAsync(data)
37
+ }
38
+ const item : T = await this._repository.update(id, data)
39
+ return item
40
+ } catch (e) {
41
+ console.error("Error updating", e)
42
+ if (e instanceof ZodError) {
43
+ throw ZodErrorToValidationError(e, data)
44
+ }
45
+ throw e
46
+ }
47
+ }
48
+
49
+ async delete(id: string): Promise<boolean> {
50
+ try {
51
+ const deleted = await this._repository.delete(id);
52
+ return deleted;
53
+ } catch (e) {
54
+ console.error("Error deleting", e)
55
+ throw e;
56
+ }
57
+
58
+ }
59
+
60
+ async findById(id: string): Promise<T | null> {
61
+ try {
62
+ const item: T = await this._repository.findById(id);
63
+ return item
64
+ } catch (e) {
65
+ console.error("Error finding Auto by id", e)
66
+ throw e;
67
+ }
68
+ }
69
+
70
+ async findByIds(ids: Array<string>): Promise<T[]> {
71
+ try {
72
+ const items: T[] = await this._repository.findByIds(ids);
73
+ return items
74
+ } catch (e) {
75
+ console.error("Error finding Auto by id", e)
76
+ throw e;
77
+ }
78
+ }
79
+
80
+ async findOneBy(field: string, value: string): Promise<T | null> {
81
+ try {
82
+ const item: T = await this._repository.findOneBy(field, value);
83
+ return item
84
+ } catch (e) {
85
+ console.error("Error finding Auto findOneBy", e)
86
+ throw e;
87
+ }
88
+
89
+ }
90
+
91
+ async findBy(field: string, value: string): Promise<T[] | null> {
92
+ try {
93
+ const items: T[] = await this._repository.findBy(field, value);
94
+ return items
95
+ } catch (e) {
96
+ console.error("Error finding Auto findBy", e)
97
+ throw e;
98
+ }
99
+
100
+ }
101
+
102
+ async fetchAll(): Promise<T[]> {
103
+ try {
104
+ const items: T[] = await this._repository.fetchAll();
105
+ return items
106
+ } catch (e) {
107
+ console.error("Error fetching all Autos", e)
108
+ throw e;
109
+ }
110
+
111
+ }
112
+
113
+ async search(value: string): Promise<T[]> {
114
+ try {
115
+ const items: T[] = await this._repository.search(value);
116
+ return items
117
+ } catch (e) {
118
+ console.error("Error fetching all Autos", e)
119
+ throw e;
120
+ }
121
+
122
+ }
123
+
124
+ async paginate({
125
+ page = 1,
126
+ limit = 5,
127
+ orderBy = '',
128
+ order = false,
129
+ search = '',
130
+ filters = []
131
+ }: IDraxPaginateOptions): Promise<IDraxPaginateResult<T>> {
132
+ try {
133
+ const pagination = await this._repository.paginate({page, limit, orderBy, order, search, filters});
134
+ return pagination;
135
+ } catch (e) {
136
+ console.error("Error paginating", e)
137
+ throw e;
138
+ }
139
+
140
+ }
141
+
142
+ }
143
+
144
+ export default AbstractService
145
+ export {AbstractService}