@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.
- package/dist/controllers/AbstractFastifyController.js +193 -0
- package/dist/index.js +8 -0
- package/dist/interfaces/ICrudRepository.js +1 -0
- package/dist/interfaces/IEntityPermission.js +1 -0
- package/dist/interfaces/IEntityRepository.js +1 -0
- package/dist/repository/AbstractMongoRepository.js +87 -0
- package/dist/repository/AbstractSqliteRepository.js +121 -0
- package/dist/services/AbstractService.js +122 -0
- package/package.json +45 -0
- package/src/controllers/AbstractFastifyController.ts +209 -0
- package/src/index.ts +19 -0
- package/src/interfaces/ICrudRepository.ts +16 -0
- package/src/interfaces/IEntityPermission.ts +10 -0
- package/src/repository/AbstractMongoRepository.ts +118 -0
- package/src/repository/AbstractSqliteRepository.ts +170 -0
- package/src/services/AbstractService.ts +145 -0
- package/tsconfig.json +16 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/types/controllers/AbstractFastifyController.d.ts +37 -0
- package/types/controllers/AbstractFastifyController.d.ts.map +1 -0
- package/types/index.d.ts +8 -0
- package/types/index.d.ts.map +1 -0
- package/types/interfaces/ICrudRepository.d.ts +15 -0
- package/types/interfaces/ICrudRepository.d.ts.map +1 -0
- package/types/interfaces/IEntityPermission.d.ts +10 -0
- package/types/interfaces/IEntityPermission.d.ts.map +1 -0
- package/types/interfaces/IEntityRepository.d.ts +5 -0
- package/types/interfaces/IEntityRepository.d.ts.map +1 -0
- package/types/repository/AbstractMongoRepository.d.ts +23 -0
- package/types/repository/AbstractMongoRepository.d.ts.map +1 -0
- package/types/repository/AbstractSqliteRepository.d.ts +24 -0
- package/types/repository/AbstractSqliteRepository.d.ts.map +1 -0
- package/types/services/AbstractService.d.ts +21 -0
- package/types/services/AbstractService.d.ts.map +1 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { ValidationError } from "@drax/common-back";
|
|
2
|
+
import { UnauthorizedError } from "@drax/identity-back";
|
|
3
|
+
class AbstractFastifyController {
|
|
4
|
+
constructor(service, permission) {
|
|
5
|
+
this.service = service;
|
|
6
|
+
this.permission = permission;
|
|
7
|
+
console.log("AbstractFastifyController created. Permissions", this.permission);
|
|
8
|
+
}
|
|
9
|
+
async findById(request, reply) {
|
|
10
|
+
try {
|
|
11
|
+
request.rbac.assertPermission(this.permission.View);
|
|
12
|
+
if (!request.params.id) {
|
|
13
|
+
reply.statusCode = 400;
|
|
14
|
+
reply.send({ error: 'BAD REQUEST' });
|
|
15
|
+
}
|
|
16
|
+
const id = request.params.id;
|
|
17
|
+
let item = await this.service.findById(id);
|
|
18
|
+
return item;
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
console.error(e);
|
|
22
|
+
if (e instanceof ValidationError) {
|
|
23
|
+
reply.statusCode = e.statusCode;
|
|
24
|
+
reply.send({ error: e.message, inputErrors: e.errors });
|
|
25
|
+
}
|
|
26
|
+
else if (e instanceof UnauthorizedError) {
|
|
27
|
+
reply.statusCode = e.statusCode;
|
|
28
|
+
reply.send({ error: e.message });
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
reply.statusCode = 500;
|
|
32
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async findByIds(request, reply) {
|
|
37
|
+
try {
|
|
38
|
+
request.rbac.assertPermission(this.permission.View);
|
|
39
|
+
if (!request.params.ids) {
|
|
40
|
+
reply.statusCode = 400;
|
|
41
|
+
reply.send({ error: 'BAD REQUEST' });
|
|
42
|
+
}
|
|
43
|
+
const ids = request.params.ids.split(",");
|
|
44
|
+
let items = await this.service.findByIds(ids);
|
|
45
|
+
return items;
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
console.error(e);
|
|
49
|
+
if (e instanceof ValidationError) {
|
|
50
|
+
reply.statusCode = e.statusCode;
|
|
51
|
+
reply.send({ error: e.message, inputErrors: e.errors });
|
|
52
|
+
}
|
|
53
|
+
else if (e instanceof UnauthorizedError) {
|
|
54
|
+
reply.statusCode = e.statusCode;
|
|
55
|
+
reply.send({ error: e.message });
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
reply.statusCode = 500;
|
|
59
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async search(request, reply) {
|
|
64
|
+
try {
|
|
65
|
+
request.rbac.assertPermission(this.permission.View);
|
|
66
|
+
const search = request.query.search;
|
|
67
|
+
let item = await this.service.search(search);
|
|
68
|
+
return item;
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
console.error(e);
|
|
72
|
+
if (e instanceof ValidationError) {
|
|
73
|
+
reply.statusCode = e.statusCode;
|
|
74
|
+
reply.send({ error: e.message, inputErrors: e.errors });
|
|
75
|
+
}
|
|
76
|
+
else if (e instanceof UnauthorizedError) {
|
|
77
|
+
reply.statusCode = e.statusCode;
|
|
78
|
+
reply.send({ error: e.message });
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
reply.statusCode = 500;
|
|
82
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async paginate(request, reply) {
|
|
87
|
+
try {
|
|
88
|
+
request.rbac.assertPermission(this.permission.View);
|
|
89
|
+
const page = request.query.page;
|
|
90
|
+
const limit = request.query.limit;
|
|
91
|
+
const orderBy = request.query.orderBy;
|
|
92
|
+
const order = request.query.order;
|
|
93
|
+
const search = request.query.search;
|
|
94
|
+
let paginateResult = await this.service.paginate({ page, limit, orderBy, order, search });
|
|
95
|
+
return paginateResult;
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
console.error(e);
|
|
99
|
+
if (e instanceof ValidationError) {
|
|
100
|
+
reply.statusCode = e.statusCode;
|
|
101
|
+
reply.send({ error: e.message, inputErrors: e.errors });
|
|
102
|
+
}
|
|
103
|
+
else if (e instanceof UnauthorizedError) {
|
|
104
|
+
reply.statusCode = e.statusCode;
|
|
105
|
+
reply.send({ error: e.message });
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
reply.statusCode = 500;
|
|
109
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async create(request, reply) {
|
|
114
|
+
try {
|
|
115
|
+
request.rbac.assertPermission(this.permission.Create);
|
|
116
|
+
const payload = request.body;
|
|
117
|
+
let item = await this.service.create(payload);
|
|
118
|
+
return item;
|
|
119
|
+
}
|
|
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
|
+
}
|
|
126
|
+
else if (e instanceof UnauthorizedError) {
|
|
127
|
+
reply.statusCode = e.statusCode;
|
|
128
|
+
reply.send({ error: e.message });
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
reply.statusCode = 500;
|
|
132
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async update(request, reply) {
|
|
137
|
+
try {
|
|
138
|
+
request.rbac.assertPermission(this.permission.Update);
|
|
139
|
+
if (!request.params.id) {
|
|
140
|
+
reply.statusCode = 400;
|
|
141
|
+
reply.send({ error: 'BAD REQUEST' });
|
|
142
|
+
}
|
|
143
|
+
const id = request.params.id;
|
|
144
|
+
const payload = request.body;
|
|
145
|
+
let item = await this.service.update(id, payload);
|
|
146
|
+
return item;
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
console.error(e);
|
|
150
|
+
if (e instanceof ValidationError) {
|
|
151
|
+
reply.statusCode = e.statusCode;
|
|
152
|
+
reply.send({ error: e.message, inputErrors: e.errors });
|
|
153
|
+
}
|
|
154
|
+
else if (e instanceof UnauthorizedError) {
|
|
155
|
+
reply.statusCode = e.statusCode;
|
|
156
|
+
reply.send({ error: e.message });
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
reply.statusCode = 500;
|
|
160
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
async delete(request, reply) {
|
|
165
|
+
try {
|
|
166
|
+
request.rbac.assertPermission(this.permission.Delete);
|
|
167
|
+
if (!request.params.id) {
|
|
168
|
+
reply.statusCode = 400;
|
|
169
|
+
reply.send({ error: 'BAD REQUEST' });
|
|
170
|
+
}
|
|
171
|
+
const id = request.params.id;
|
|
172
|
+
await this.service.delete(id);
|
|
173
|
+
reply.send({ message: 'Item deleted successfully' });
|
|
174
|
+
}
|
|
175
|
+
catch (e) {
|
|
176
|
+
console.error(e);
|
|
177
|
+
if (e instanceof ValidationError) {
|
|
178
|
+
reply.statusCode = e.statusCode;
|
|
179
|
+
reply.send({ error: e.message, inputErrors: e.errors });
|
|
180
|
+
}
|
|
181
|
+
else if (e instanceof UnauthorizedError) {
|
|
182
|
+
reply.statusCode = e.statusCode;
|
|
183
|
+
reply.send({ error: e.message });
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
reply.statusCode = 500;
|
|
187
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
export default AbstractFastifyController;
|
|
193
|
+
export { AbstractFastifyController };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
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
|
+
export {
|
|
7
|
+
//CRUD
|
|
8
|
+
AbstractMongoRepository, AbstractSqliteRepository, AbstractService, AbstractFastifyController, };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import "mongoose-paginate-v2";
|
|
2
|
+
import mongoose from "mongoose";
|
|
3
|
+
import { MongooseQueryFilter, MongooseSort, MongooseErrorToValidationError } from "@drax/common-back";
|
|
4
|
+
class AbstractMongoRepository {
|
|
5
|
+
constructor() {
|
|
6
|
+
this._searchFields = [];
|
|
7
|
+
this._populateFields = [];
|
|
8
|
+
}
|
|
9
|
+
async create(data) {
|
|
10
|
+
try {
|
|
11
|
+
const item = new this._model(data);
|
|
12
|
+
await item.save();
|
|
13
|
+
//@ts-ignore
|
|
14
|
+
await item.populate(this._populateFields);
|
|
15
|
+
return item;
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
if (e instanceof mongoose.Error.ValidationError) {
|
|
19
|
+
throw MongooseErrorToValidationError(e);
|
|
20
|
+
}
|
|
21
|
+
throw e;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async update(id, data) {
|
|
25
|
+
try {
|
|
26
|
+
const item = await this._model.findOneAndUpdate({ _id: id }, data, { new: true }).populate(this._populateFields).exec();
|
|
27
|
+
return item;
|
|
28
|
+
}
|
|
29
|
+
catch (e) {
|
|
30
|
+
if (e instanceof mongoose.Error.ValidationError) {
|
|
31
|
+
throw MongooseErrorToValidationError(e);
|
|
32
|
+
}
|
|
33
|
+
throw e;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async delete(id) {
|
|
37
|
+
const result = await this._model.deleteOne({ _id: id }).exec();
|
|
38
|
+
return result.deletedCount == 1;
|
|
39
|
+
}
|
|
40
|
+
async findById(id) {
|
|
41
|
+
const item = await this._model.findById(id).populate(this._populateFields).exec();
|
|
42
|
+
return item;
|
|
43
|
+
}
|
|
44
|
+
async findByIds(ids) {
|
|
45
|
+
const items = await this._model.find({ _id: { $in: ids } }).populate(this._populateFields).exec();
|
|
46
|
+
return items;
|
|
47
|
+
}
|
|
48
|
+
async findOneBy(field, value) {
|
|
49
|
+
const filter = { [field]: value };
|
|
50
|
+
const item = await this._model.findOne(filter).populate(this._populateFields).exec();
|
|
51
|
+
return item;
|
|
52
|
+
}
|
|
53
|
+
async findBy(field, value) {
|
|
54
|
+
const filter = { [field]: value };
|
|
55
|
+
const items = await this._model.find(filter).populate(this._populateFields).exec();
|
|
56
|
+
return items;
|
|
57
|
+
}
|
|
58
|
+
async fetchAll() {
|
|
59
|
+
const items = await this._model.find().populate(this._populateFields).exec();
|
|
60
|
+
return items;
|
|
61
|
+
}
|
|
62
|
+
async search(value, limit = 1000) {
|
|
63
|
+
const query = {};
|
|
64
|
+
query['$or'] = this._searchFields.map(field => ({ [field]: new RegExp(value, 'i') }));
|
|
65
|
+
const items = await this._model.find(query).limit(limit).exec();
|
|
66
|
+
return items;
|
|
67
|
+
}
|
|
68
|
+
async paginate({ page = 1, limit = 5, orderBy = '', order = false, search = '', filters = [] }) {
|
|
69
|
+
const query = {};
|
|
70
|
+
if (search) {
|
|
71
|
+
query['$or'] = this._searchFields.map(field => ({ [field]: new RegExp(search, 'i') }));
|
|
72
|
+
}
|
|
73
|
+
MongooseQueryFilter.applyFilters(query, filters);
|
|
74
|
+
const sort = MongooseSort.applySort(orderBy, order);
|
|
75
|
+
const populate = this._populateFields;
|
|
76
|
+
const options = { page, limit, sort, populate };
|
|
77
|
+
const items = await this._model.paginate(query, options);
|
|
78
|
+
return {
|
|
79
|
+
page: page,
|
|
80
|
+
limit: limit,
|
|
81
|
+
total: items.totalDocs,
|
|
82
|
+
items: items.docs
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export default AbstractMongoRepository;
|
|
87
|
+
export { AbstractMongoRepository };
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import sqlite from "better-sqlite3";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { SqlSort, SqlQueryFilter, SqliteTableBuilder, SqliteErrorToValidationError } from "@drax/common-back";
|
|
4
|
+
class AbstractSqliteRepository {
|
|
5
|
+
constructor(dataBase, tableName, identifier = 'id', searchFields = [], booleanFields = [], verbose = false) {
|
|
6
|
+
this.searchFields = [];
|
|
7
|
+
this.booleanFields = [];
|
|
8
|
+
this.identifier = 'id';
|
|
9
|
+
if (!dataBase) {
|
|
10
|
+
throw new Error("dataBase is required");
|
|
11
|
+
}
|
|
12
|
+
if (!tableName) {
|
|
13
|
+
throw new Error("tableName is required");
|
|
14
|
+
}
|
|
15
|
+
this.dataBase = dataBase;
|
|
16
|
+
this.tableName = tableName;
|
|
17
|
+
this.identifier = identifier;
|
|
18
|
+
this.searchFields = searchFields;
|
|
19
|
+
this.booleanFields = booleanFields;
|
|
20
|
+
this.verbose = verbose;
|
|
21
|
+
this.db = new sqlite(dataBase, { verbose: verbose ? console.log : null });
|
|
22
|
+
}
|
|
23
|
+
build() {
|
|
24
|
+
const builder = new SqliteTableBuilder(this.dataBase, this.tableName, this.tableFields, this.verbose);
|
|
25
|
+
builder.build(this.identifier);
|
|
26
|
+
}
|
|
27
|
+
async create(data) {
|
|
28
|
+
try {
|
|
29
|
+
if (!data[this.identifier]) {
|
|
30
|
+
data[this.identifier] = randomUUID();
|
|
31
|
+
}
|
|
32
|
+
for (const key in data) {
|
|
33
|
+
if (typeof data[key] === 'boolean') {
|
|
34
|
+
data[key] = data[key] ? 1 : 0;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const fields = Object.keys(data)
|
|
38
|
+
.map(field => `${field}`)
|
|
39
|
+
.join(', ');
|
|
40
|
+
const values = Object.keys(data)
|
|
41
|
+
.map(field => `@${field}`)
|
|
42
|
+
.join(', ');
|
|
43
|
+
const stmt = this.db.prepare(`INSERT INTO ${this.tableName} (${fields}) VALUES (${values})`);
|
|
44
|
+
stmt.run(data);
|
|
45
|
+
return this.findById(data[this.identifier]);
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
console.log(e);
|
|
49
|
+
throw SqliteErrorToValidationError(e, data);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async findById(id) {
|
|
53
|
+
const item = this.db.prepare(`SELECT * FROM ${this.tableName} WHERE ${this.identifier} = ?`).get(id);
|
|
54
|
+
return item;
|
|
55
|
+
}
|
|
56
|
+
async findBy(field, value) {
|
|
57
|
+
const item = this.db.prepare(`SELECT * FROM ${this.tableName} WHERE ${field} = ?`).all(value);
|
|
58
|
+
return item;
|
|
59
|
+
}
|
|
60
|
+
async findOneBy(field, value) {
|
|
61
|
+
const item = this.db.prepare(`SELECT * FROM ${this.tableName} WHERE ${field} = ?`).get(value);
|
|
62
|
+
return item;
|
|
63
|
+
}
|
|
64
|
+
async update(id, data) {
|
|
65
|
+
try {
|
|
66
|
+
for (const key in data) {
|
|
67
|
+
if (typeof data[key] === 'boolean') {
|
|
68
|
+
data[key] = data[key] ? 1 : 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const setClauses = Object.keys(data)
|
|
72
|
+
.map(field => `${field} = @${field}`)
|
|
73
|
+
.join(', ');
|
|
74
|
+
data.identifier = id;
|
|
75
|
+
const stmt = this.db.prepare(`UPDATE ${this.tableName} SET ${setClauses} WHERE ${this.identifier} = @identifier `);
|
|
76
|
+
stmt.run(data);
|
|
77
|
+
return this.findById(id);
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
console.log(e);
|
|
81
|
+
throw SqliteErrorToValidationError(e, data);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async delete(id) {
|
|
85
|
+
const stmt = this.db.prepare(`DELETE FROM ${this.tableName} WHERE ${this.identifier} = ?`);
|
|
86
|
+
stmt.run(id);
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
async paginate({ page = 1, limit = 5, orderBy = '', order = 'desc', search = '', filters = [] }) {
|
|
90
|
+
const offset = page > 1 ? (page - 1) * limit : 0;
|
|
91
|
+
let where = "";
|
|
92
|
+
if (search && this.searchFields.length > 0) {
|
|
93
|
+
where = ` WHERE ${this.searchFields.map(field => `${field} LIKE '%${search}%'`).join(" OR ")}`;
|
|
94
|
+
}
|
|
95
|
+
if (filters.length > 0) {
|
|
96
|
+
where = SqlQueryFilter.applyFilters(where, filters);
|
|
97
|
+
}
|
|
98
|
+
const sort = SqlSort.applySort(orderBy, order);
|
|
99
|
+
const rCount = this.db.prepare(`SELECT COUNT(*) as count FROM ${this.tableName} ${where}`).get();
|
|
100
|
+
const items = this.db.prepare(`SELECT * FROM ${this.tableName} ${where} ${sort} LIMIT ? OFFSET ? `).all([limit, offset]);
|
|
101
|
+
for (const item of items) {
|
|
102
|
+
for (const key in item) {
|
|
103
|
+
if (this.booleanFields.includes(key)) {
|
|
104
|
+
//@ts-ignore
|
|
105
|
+
item[key] = item[key] ? true : false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
page: page,
|
|
111
|
+
limit: limit,
|
|
112
|
+
total: rCount.count,
|
|
113
|
+
items: items
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
async fetchAll() {
|
|
117
|
+
const tenants = this.db.prepare(`SELECT * FROM ${this.tableName}`).all();
|
|
118
|
+
return tenants;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export default AbstractSqliteRepository;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { ZodErrorToValidationError } from "@drax/common-back";
|
|
2
|
+
import { ZodError } from "zod";
|
|
3
|
+
class AbstractService {
|
|
4
|
+
constructor(repository, schema) {
|
|
5
|
+
this._repository = repository;
|
|
6
|
+
this._schema = schema;
|
|
7
|
+
}
|
|
8
|
+
async create(data) {
|
|
9
|
+
try {
|
|
10
|
+
if (this._schema) {
|
|
11
|
+
await this._schema.parseAsync(data);
|
|
12
|
+
}
|
|
13
|
+
const item = await this._repository.create(data);
|
|
14
|
+
return item;
|
|
15
|
+
}
|
|
16
|
+
catch (e) {
|
|
17
|
+
console.error("Error creating", e);
|
|
18
|
+
if (e instanceof ZodError) {
|
|
19
|
+
throw ZodErrorToValidationError(e, data);
|
|
20
|
+
}
|
|
21
|
+
throw e;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async update(id, data) {
|
|
25
|
+
try {
|
|
26
|
+
if (this._schema) {
|
|
27
|
+
await this._schema.parseAsync(data);
|
|
28
|
+
}
|
|
29
|
+
const item = await this._repository.update(id, data);
|
|
30
|
+
return item;
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
console.error("Error updating", e);
|
|
34
|
+
if (e instanceof ZodError) {
|
|
35
|
+
throw ZodErrorToValidationError(e, data);
|
|
36
|
+
}
|
|
37
|
+
throw e;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async delete(id) {
|
|
41
|
+
try {
|
|
42
|
+
const deleted = await this._repository.delete(id);
|
|
43
|
+
return deleted;
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
console.error("Error deleting", e);
|
|
47
|
+
throw e;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async findById(id) {
|
|
51
|
+
try {
|
|
52
|
+
const item = await this._repository.findById(id);
|
|
53
|
+
return item;
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
console.error("Error finding Auto by id", e);
|
|
57
|
+
throw e;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async findByIds(ids) {
|
|
61
|
+
try {
|
|
62
|
+
const items = await this._repository.findByIds(ids);
|
|
63
|
+
return items;
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
console.error("Error finding Auto by id", e);
|
|
67
|
+
throw e;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async findOneBy(field, value) {
|
|
71
|
+
try {
|
|
72
|
+
const item = await this._repository.findOneBy(field, value);
|
|
73
|
+
return item;
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
console.error("Error finding Auto findOneBy", e);
|
|
77
|
+
throw e;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async findBy(field, value) {
|
|
81
|
+
try {
|
|
82
|
+
const items = await this._repository.findBy(field, value);
|
|
83
|
+
return items;
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
console.error("Error finding Auto findBy", e);
|
|
87
|
+
throw e;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async fetchAll() {
|
|
91
|
+
try {
|
|
92
|
+
const items = await this._repository.fetchAll();
|
|
93
|
+
return items;
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
console.error("Error fetching all Autos", e);
|
|
97
|
+
throw e;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async search(value) {
|
|
101
|
+
try {
|
|
102
|
+
const items = await this._repository.search(value);
|
|
103
|
+
return items;
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
console.error("Error fetching all Autos", e);
|
|
107
|
+
throw e;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async paginate({ page = 1, limit = 5, orderBy = '', order = false, search = '', filters = [] }) {
|
|
111
|
+
try {
|
|
112
|
+
const pagination = await this._repository.paginate({ page, limit, orderBy, order, search, filters });
|
|
113
|
+
return pagination;
|
|
114
|
+
}
|
|
115
|
+
catch (e) {
|
|
116
|
+
console.error("Error paginating", e);
|
|
117
|
+
throw e;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
export default AbstractService;
|
|
122
|
+
export { AbstractService };
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@drax/crud-back",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.4.0",
|
|
7
|
+
"description": "Crud utils across modules",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "types/index.d.ts",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"prepublish": "tsc && npm run copygql",
|
|
13
|
+
"tscrun": "tsc",
|
|
14
|
+
"clean": "rm -rf dist",
|
|
15
|
+
"copygql": "copyfiles -u 1 ./**/*.graphql dist/",
|
|
16
|
+
"tsc": "tsc -b tsconfig.json",
|
|
17
|
+
"test": "node --import tsx --test test/**/*",
|
|
18
|
+
"testCache": "node --import tsx --test test/cache/*",
|
|
19
|
+
"testMongoose": "node --import tsx --test test/mongoose/*"
|
|
20
|
+
},
|
|
21
|
+
"author": "Cristian Incarnato & Drax Team",
|
|
22
|
+
"license": "ISC",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@drax/common-back": "^0.4.0",
|
|
25
|
+
"@drax/common-share": "^0.4.0",
|
|
26
|
+
"@graphql-tools/load-files": "^7.0.0",
|
|
27
|
+
"@graphql-tools/merge": "^9.0.4",
|
|
28
|
+
"mongoose": "^8.6.3",
|
|
29
|
+
"mongoose-paginate-v2": "^1.8.3"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"dayjs": "^1.11.13",
|
|
33
|
+
"mongoose-paginate-v2": "^1.8.3"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^20.12.10",
|
|
37
|
+
"copyfiles": "^2.4.1",
|
|
38
|
+
"mongoose-paginate-v2": "^1.8.3",
|
|
39
|
+
"nodemon": "^3.1.0",
|
|
40
|
+
"ts-node": "^10.9.2",
|
|
41
|
+
"tsc-alias": "^1.8.10",
|
|
42
|
+
"typescript": "^5.6.2"
|
|
43
|
+
},
|
|
44
|
+
"gitHead": "481b302fe72f403abf092806ceca540dd2765dfa"
|
|
45
|
+
}
|